Cataclysm BN
map Class Reference

Manage and cache data about a part of the map. More...

#include <map.h>

Inheritance diagram for map:
tinymap fake_map

Classes

struct  apparent_light_info
 

Public Member Functions

 map (int mapsize=MAPSIZE, bool zlev=false)
 
 map (bool zlev)
 
virtual ~map ()
 
mapoperator= (const map &)=delete
 
mapoperator= (map &&)
 
void set_transparency_cache_dirty (const int zlev)
 Sets a dirty flag on the a given cache. More...
 
void set_transparency_cache_dirty (const tripoint &p)
 
void set_seen_cache_dirty (const tripoint change_location)
 
void set_seen_cache_dirty (const int zlevel)
 
void set_outside_cache_dirty (const int zlev)
 
void set_floor_cache_dirty (const int zlev)
 
void set_suspension_cache_dirty (const int zlev)
 
void set_pathfinding_cache_dirty (int zlev)
 
void set_memory_seen_cache_dirty (const tripoint &p)
 
void invalidate_map_cache (const int zlev)
 
bool check_seen_cache (const tripoint &p) const
 
bool check_and_set_seen_cache (const tripoint &p) const
 
void on_vehicle_moved (int smz)
 Callback invoked when a vehicle has moved. More...
 
lit_level apparent_light_at (const tripoint &p, const visibility_variables &cache) const
 Determine the visible light level for a tile, based on light_at for the tile, vision distance, etc. More...
 
visibility_type get_visibility (lit_level ll, const visibility_variables &cache) const
 
std::tuple< maptile, maptile, maptileget_wind_blockers (const int &winddirection, const tripoint &pos)
 
void draw (const catacurses::window &w, const tripoint &center)
 Draw a visible part of the map into w. More...
 
void drawsq (const catacurses::window &w, const tripoint &p, const drawsq_params &params) const
 Draw the map tile at the given coordinate. More...
 
void save ()
 Add currently loaded submaps (in grid) to the mapbuffer. More...
 
void load (const tripoint &w, bool update_vehicles, bool pump_events=false)
 Load submaps into grid. More...
 
void load (const tripoint_abs_sm &w, bool update_vehicles, bool pump_events=false)
 
void shift (const point &s)
 Shift the map along the vector s. More...
 
void vertical_shift (int newz)
 Moves the map vertically to (not by!) newz. More...
 
void clear_spawns ()
 
void clear_traps ()
 
maptile maptile_at (const tripoint &p) const
 
maptile maptile_at (const tripoint &p)
 
int move_cost (const tripoint &p, const vehicle *ignored_vehicle=nullptr) const
 Calculate the cost to move past the tile at p. More...
 
int move_cost (const point &p, const vehicle *ignored_vehicle=nullptr) const
 
bool impassable (const tripoint &p) const
 
bool impassable (const point &p) const
 
bool passable (const tripoint &p) const
 
bool passable (const point &p) const
 
bool is_wall_adjacent (const tripoint &center) const
 
int move_cost_ter_furn (const tripoint &p) const
 Similar behavior to move_cost(), but ignores vehicles. More...
 
int move_cost_ter_furn (const point &p) const
 
bool impassable_ter_furn (const tripoint &p) const
 
bool passable_ter_furn (const tripoint &p) const
 
int combined_movecost (const tripoint &from, const tripoint &to, const vehicle *ignored_vehicle=nullptr, int modifier=0, bool flying=false, bool via_ramp=false) const
 Cost to move out of one tile and into the next. More...
 
bool valid_move (const tripoint &from, const tripoint &to, bool bash=false, bool flying=false, bool via_ramp=false) const
 Returns true if a creature could walk from from to to in one step. More...
 
double ranged_target_size (const tripoint &p) const
 Size of map objects at p for purposes of ranged combat. More...
 
bool sees (const tripoint &F, const tripoint &T, int range) const
 Returns whether F sees T with a view range of range. More...
 
int obstacle_coverage (const tripoint &loc1, const tripoint &loc2) const
 Returns coverage of target in relation to the observer. More...
 
int coverage (const tripoint &p) const
 Returns coverage value of the tile. More...
 
bool clear_path (const tripoint &f, const tripoint &t, int range, int cost_min, int cost_max) const
 Check whether there's a direct line of sight between F and T with the additional movecost restraints. More...
 
bool obstructed_by_vehicle_rotation (const tripoint &from, const tripoint &to) const
 Checks if a rotated vehicle is blocking diagonal movement, tripoints must be adjacent. More...
 
bool obscured_by_vehicle_rotation (const tripoint &from, const tripoint &to) const
 Checks if a rotated vehicle is blocking diagonal vision, tripoints must be adjacent. More...
 
void reachable_flood_steps (std::vector< tripoint > &reachable_pts, const tripoint &f, int range, int cost_min, int cost_max) const
 Populates a vector of points that are reachable within a number of steps from a point. More...
 
std::vector< tripointfind_clear_path (const tripoint &source, const tripoint &destination) const
 Iteratively tries Bresenham lines with different biases until it finds a clear line or decides there isn't one. More...
 
bool accessible_items (const tripoint &t) const
 Check whether the player can access the items located . More...
 
std::vector< tripointget_dir_circle (const tripoint &f, const tripoint &t) const
 Calculate next search points surrounding the current position. More...
 
std::vector< tripointroute (const tripoint &f, const tripoint &t, const pathfinding_settings &settings, const std::set< tripoint > &pre_closed={{ }}) const
 Calculate the best path using A*. More...
 
VehicleList get_vehicles ()
 
void add_vehicle_to_cache (vehicle *)
 
void clear_vehicle_point_from_cache (vehicle *veh, const tripoint &pt)
 
void update_vehicle_cache (vehicle *, int old_zlevel)
 
void reset_vehicle_cache ()
 
void clear_vehicle_cache ()
 
void clear_vehicle_list (int zlev)
 
void update_vehicle_list (const submap *to, int zlev)
 
bool check_vehicle_zones (int zlev)
 
std::vector< zone_data * > get_vehicle_zones (int zlev)
 
void register_vehicle_zone (vehicle *, int zlev)
 
bool deregister_vehicle_zone (zone_data &zone)
 
std::unique_ptr< vehicledetach_vehicle (vehicle *veh)
 
void destroy_vehicle (vehicle *veh)
 
void vehmove ()
 
bool vehproceed (VehicleList &vehicle_list)
 
VehicleList get_vehicles (const tripoint &start, const tripoint &end)
 
optional_vpart_position veh_at (const tripoint &p) const
 Checks if tile is occupied by vehicle and by which part. More...
 
vehicleveh_at_internal (const tripoint &p, int &part_num)
 
const vehicleveh_at_internal (const tripoint &p, int &part_num) const
 
void board_vehicle (const tripoint &p, player *pl)
 
void unboard_vehicle (const vpart_reference &, Character *passenger, bool dead_passenger=false)
 
void unboard_vehicle (const tripoint &p, bool dead_passenger=false)
 
bool displace_vehicle (vehicle &veh, const tripoint &dp)
 
void shift_vehicle_z (vehicle &veh, int z_shift)
 
bool displace_water (const tripoint &dp)
 
float vehicle_wheel_traction (const vehicle &veh, bool ignore_movement_modifiers=false) const
 
float vehicle_vehicle_collision (vehicle &veh, vehicle &veh2, const std::vector< veh_collision > &collisions)
 
units::angle shake_vehicle (vehicle &veh, int velocity_before, units::angle direction)
 
vehiclemove_vehicle (vehicle &veh, const tripoint &dp, const tileray &facing)
 
void set (const tripoint &p, const ter_id &new_terrain, const furn_id &new_furniture)
 
void set (const point &p, const ter_id &new_terrain, const furn_id &new_furniture)
 
std::string name (const tripoint &p)
 
std::string name (const point &p)
 
std::string disp_name (const tripoint &p)
 
std::string obstacle_name (const tripoint &p)
 Returns the name of the obstacle at p that might be blocking movement/projectiles/etc. More...
 
bool has_furn (const tripoint &p) const
 
bool has_furn (const point &p) const
 
furn_id furn (const tripoint &p) const
 
furn_id furn (const point &p) const
 
void furn_set (const tripoint &p, const furn_id &new_furniture, cata::poly_serialized< active_tile_data > new_active=nullptr)
 Sets the furniture at given position. More...
 
void furn_set (const point &p, const furn_id &new_furniture)
 
std::string furnname (const tripoint &p)
 
std::string furnname (const point &p)
 
bool can_move_furniture (const tripoint &pos, player *p=nullptr)
 
ter_id ter (const tripoint &p) const
 
ter_id ter (const point &p) const
 
uint8_t get_known_connections (const tripoint &p, int connect_group, const std::map< tripoint, ter_id > &override={}) const
 
const harvest_idget_harvest (const tripoint &p) const
 Returns the full harvest list, for spawning. More...
 
const std::set< std::string > & get_harvest_names (const tripoint &p) const
 Returns names of the items that would be dropped. More...
 
ter_id get_ter_transforms_into (const tripoint &p) const
 
furn_id get_furn_transforms_into (const tripoint &p) const
 
bool ter_set (const tripoint &p, const ter_id &new_terrain)
 
bool ter_set (const point &p, const ter_id &new_terrain)
 
std::string tername (const tripoint &p) const
 
std::string tername (const point &p) const
 
bool has_nearby_fire (const tripoint &p, int radius=1)
 
bool has_nearby_table (const tripoint &p, int radius=1)
 Check whether a table/workbench/vehicle kitchen or other flat surface is nearby that could be used for crafting or eating. More...
 
bool has_nearby_chair (const tripoint &p, int radius=1)
 Check whether a chair or vehicle seat is nearby. More...
 
bool sees_some_items (const tripoint &p, const Creature &who) const
 Check if creature can see some items at p. More...
 
bool sees_some_items (const tripoint &p, const tripoint &from) const
 
bool could_see_items (const tripoint &p, const Creature &who) const
 Check if the creature could see items at p if there were any items. More...
 
bool could_see_items (const tripoint &p, const tripoint &from) const
 
bool has_items (const tripoint &p) const
 Checks for existence of items. More...
 
void examine (Character &p, const tripoint &pos)
 Calls the examine function of furniture or terrain at given tile, for given character. More...
 
bool is_harvestable (const tripoint &pos) const
 Returns true if point at pos is harvestable right now, with no extra tools. More...
 
std::string features (const tripoint &p)
 
std::string features (const point &p)
 
bool has_flag (const std::string &flag, const tripoint &p) const
 
bool has_flag (const std::string &flag, const point &p) const
 
bool can_put_items (const tripoint &p) const
 
bool can_put_items (const point &p) const
 
bool can_put_items_ter_furn (const tripoint &p) const
 
bool can_put_items_ter_furn (const point &p) const
 
bool has_flag_ter (const std::string &flag, const tripoint &p) const
 
bool has_flag_ter (const std::string &flag, const point &p) const
 
bool has_flag_furn (const std::string &flag, const tripoint &p) const
 
bool has_flag_furn (const std::string &flag, const point &p) const
 
bool has_flag_ter_or_furn (const std::string &flag, const tripoint &p) const
 
bool has_flag_ter_or_furn (const std::string &flag, const point &p) const
 
bool has_flag (ter_bitflags flag, const tripoint &p) const
 
bool has_flag (ter_bitflags flag, const point &p) const
 
bool has_flag_ter (ter_bitflags flag, const tripoint &p) const
 
bool has_flag_ter (ter_bitflags flag, const point &p) const
 
bool has_flag_furn (ter_bitflags flag, const tripoint &p) const
 
bool has_flag_furn (ter_bitflags flag, const point &p) const
 
bool has_flag_ter_or_furn (ter_bitflags flag, const tripoint &p) const
 
bool has_flag_ter_or_furn (ter_bitflags flag, const point &p) const
 
bool is_bashable (const tripoint &p, bool allow_floor=false) const
 Returns true if there is a bashable vehicle part or the furn/terrain is bashable at p. More...
 
bool is_bashable (const point &p) const
 
bool is_bashable_ter (const tripoint &p, bool allow_floor=false) const
 Returns true if the terrain at p is bashable. More...
 
bool is_bashable_ter (const point &p) const
 
bool is_bashable_furn (const tripoint &p) const
 Returns true if the furniture at p is bashable. More...
 
bool is_bashable_furn (const point &p) const
 
bool is_bashable_ter_furn (const tripoint &p, bool allow_floor=false) const
 Returns true if the furniture or terrain at p is bashable. More...
 
bool is_bashable_ter_furn (const point &p) const
 
int bash_strength (const tripoint &p, bool allow_floor=false) const
 Returns max_str of the furniture or terrain at p. More...
 
int bash_strength (const point &p) const
 
int bash_resistance (const tripoint &p, bool allow_floor=false) const
 Returns min_str of the furniture or terrain at p. More...
 
int bash_resistance (const point &p) const
 
int bash_rating (int str, const tripoint &p, bool allow_floor=false) const
 Returns a success rating from -1 to 10 for a given tile based on a set strength, used for AI movement planning Values roughly correspond to 10% increment chances of success on a given bash, rounded down. More...
 
int bash_rating (const int str, const point &p) const
 
void make_rubble (const tripoint &p, const furn_id &rubble_type, bool items, const ter_id &floor_type, bool overwrite=false)
 Generates rubble at the given location, if overwrite is true it just writes on top of what currently exists floor_type is only used if there is a non-bashable wall at the location or with overwrite = true. More...
 
void make_rubble (const tripoint &p, const furn_id &rubble_type, bool items)
 
void make_rubble (const tripoint &p)
 
bool is_outside (const tripoint &p) const
 
bool is_outside (const point &p) const
 
bool is_divable (const tripoint &p) const
 Returns whether or not the terrain at the given location can be dived into (by monsters that can swim or are aquatic or non-breathing). More...
 
bool is_divable (const point &p) const
 
bool is_water_shallow_current (const tripoint &p) const
 
bool is_water_shallow_current (const point &p) const
 
bool is_last_ter_wall (bool no_furn, const point &p, const point &max, direction dir) const
 Check if the last terrain is wall in direction NORTH, SOUTH, WEST or EAST. More...
 
bool tinder_at (const tripoint &p)
 Checks if there are any tinder flagged items on the tile. More...
 
bool flammable_items_at (const tripoint &p, int threshold=0)
 Checks if there are any flammable items on the tile. More...
 
bool is_flammable (const tripoint &p)
 Returns true if there is a flammable item or field or the furn/terrain is flammable at p. More...
 
point random_outdoor_tile ()
 
void draw_line_ter (const ter_id &type, const point &p1, const point &p2)
 
void draw_line_furn (const furn_id &type, const point &p1, const point &p2)
 
void draw_fill_background (const ter_id &type)
 
void draw_fill_background (ter_id(*f)())
 
void draw_fill_background (const weighted_int_list< ter_id > &f)
 
void draw_square_ter (const ter_id &type, const point &p1, const point &p2)
 
void draw_square_furn (const furn_id &type, const point &p1, const point &p2)
 
void draw_square_ter (ter_id(*f)(), const point &p1, const point &p2)
 
void draw_square_ter (const weighted_int_list< ter_id > &f, const point &p1, const point &p2)
 
void draw_rough_circle_ter (const ter_id &type, const point &p, int rad)
 
void draw_rough_circle_furn (const furn_id &type, const point &p, int rad)
 
void draw_circle_ter (const ter_id &type, const rl_vec2d &p, double rad)
 
void draw_circle_ter (const ter_id &type, const point &p, int rad)
 
void draw_circle_furn (const furn_id &type, const point &p, int rad)
 
void add_corpse (const tripoint &p)
 
void translate (const ter_id &from, const ter_id &to)
 
void translate_radius (const ter_id &from, const ter_id &to, float radi, const tripoint &p, bool same_submap=false, bool toggle_between=false)
 
bool close_door (const tripoint &p, bool inside, bool check_only)
 
bool open_door (const tripoint &p, bool inside, bool check_only=false)
 
void batter (const tripoint &p, int power, int tries=1, bool silent=false)
 bash a square for a set number of times at set power. More...
 
void destroy (const tripoint &p, bool silent=false)
 Keeps bashing a square until it can't be bashed anymore. More...
 
void destroy_furn (const tripoint &p, bool silent=false)
 Keeps bashing a square until there is no more furniture. More...
 
void crush (const tripoint &p)
 
void shoot (const tripoint &p, projectile &proj, bool hit_items)
 
int collapse_check (const tripoint &p)
 Checks if a square should collapse, returns the X for the one_in(X) collapse chance. More...
 
void collapse_at (const tripoint &p, bool silent, bool was_supporting=false, bool destroy_pos=true)
 Causes a collapse at p, such as from destroying a wall. More...
 
void propagate_suspension_check (const tripoint &point)
 Checks surrounding tiles for suspension, and has them check for collapse. More...
 
void collapse_invalid_suspension (const tripoint &point)
 Triggers a recursive collapse of suspended tiles based on their support validity. More...
 
bool is_suspension_valid (const tripoint &point)
 Checks the four orientations in which a suspended tile could be valid, and returns if the tile is valid. More...
 
void smash_items (const tripoint &p, int power, const std::string &cause_message, bool do_destroy)
 Tries to smash the items at the given tripoint. More...
 
bash_results bash (const tripoint &p, int str, bool silent=false, bool destroy=false, bool bash_floor=false, const vehicle *bashing_vehicle=nullptr)
 Returns a pair where first is whether anything was smashed and second is if it was destroyed. More...
 
bash_results bash_vehicle (const tripoint &p, const bash_params &params)
 
bash_results bash_ter_furn (const tripoint &p, const bash_params &params)
 
bool hit_with_acid (const tripoint &p)
 
bool hit_with_fire (const tripoint &p)
 
bool has_adjacent_furniture_with (const tripoint &p, const std::function< bool(const furn_t &)> &filter)
 Returns true if there is furniture for which filter returns true in a 1 tile radius of p. More...
 
bool mop_spills (const tripoint &p)
 Remove moppable fields/items at this location. More...
 
void decay_fields_and_scent (const time_duration &amount)
 Moved here from weather.cpp for speed. More...
 
std::string get_signage (const tripoint &p) const
 
void set_signage (const tripoint &p, const std::string &message) const
 
void delete_signage (const tripoint &p) const
 
int get_radiation (const tripoint &p) const
 
void set_radiation (const tripoint &p, int value)
 
void set_radiation (const point &p, const int value)
 
void adjust_radiation (const tripoint &p, int delta)
 Increment the radiation in the given tile by the given delta (decrement it if delta is negative) More...
 
void adjust_radiation (const point &p, const int delta)
 
int get_temperature (const tripoint &p) const
 
void set_temperature (const tripoint &p, int temperature)
 
void set_temperature (const point &p, int new_temperature)
 
std::vector< tripointcheck_submap_active_item_consistency ()
 
map_stack i_at (const tripoint &p)
 
map_stack i_at (const point &p)
 
item water_from (const tripoint &p)
 
void i_clear (const tripoint &p)
 
void i_clear (const point &p)
 
map_stack::iterator i_rem (const tripoint &p, map_stack::const_iterator it)
 
map_stack::iterator i_rem (const point &location, map_stack::const_iterator it)
 
void i_rem (const tripoint &p, item *it)
 
void i_rem (const point &p, item *it)
 
void spawn_artifact (const tripoint &p)
 
void spawn_natural_artifact (const tripoint &p, artifact_natural_property prop)
 
void spawn_item (const tripoint &p, const itype_id &type_id, unsigned quantity=1, int charges=0, const time_point &birthday=calendar::start_of_cataclysm, int damlevel=0)
 
void spawn_item (const point &p, const itype_id &type_id, unsigned quantity=1, int charges=0, const time_point &birthday=calendar::start_of_cataclysm, int damlevel=0)
 
void spawn_item (const tripoint &p, const std::string &type_id, unsigned quantity=1, int charges=0, const time_point &birthday=calendar::start_of_cataclysm, int damlevel=0)
 
void spawn_item (const point &p, const std::string &type_id, unsigned quantity=1, int charges=0, const time_point &birthday=calendar::start_of_cataclysm, int damlevel=0)
 
units::volume max_volume (const tripoint &p)
 
units::volume free_volume (const tripoint &p)
 
units::volume stored_volume (const tripoint &p)
 
itemadd_item_or_charges (const tripoint &pos, item obj, bool overflow=true)
 Adds an item to map tile or stacks charges. More...
 
itemadd_item_or_charges (const point &p, item obj, bool overflow=true)
 
itemadd_item (const tripoint &p, item new_item)
 Place an item on the map, despite the parameter name, this is not necessarily a new item. More...
 
void add_item (const point &p, item new_item)
 
itemspawn_an_item (const tripoint &p, item new_item, int charges, int damlevel)
 
void spawn_an_item (const point &p, item new_item, int charges, int damlevel)
 
void make_active (item_location &loc)
 Update an item's active status, for example when adding hot or perishable liquid to a container. More...
 
void update_lum (item_location &loc, bool add)
 Update luminosity before and after item's transformation. More...
 

Static Public Member Functions

static apparent_light_info apparent_light_helper (const level_cache &map_cache, const tripoint &p)
 Helper function for light claculation; exposed here for map editor. More...
 

Private Member Functions

maptile maptile_at_internal (const tripoint &p) const
 
maptile maptile_at_internal (const tripoint &p)
 
std::pair< tripoint, maptilemaptile_has_bounds (const tripoint &p, bool bounds_checked)
 
std::array< std::pair< tripoint, maptile >, 8 > get_neighbors (const tripoint &p)
 
void spread_gas (field_entry &cur, const tripoint &p, int percent_spread, const time_duration &outdoor_age_speedup, scent_block &sblk)
 
void create_hot_air (const tripoint &p, int intensity)
 
bool gas_can_spread_to (field_entry &cur, const tripoint &src, const tripoint &dst)
 
void gas_spread_to (field_entry &cur, maptile &dst, const tripoint &p)
 
int burn_body_part (player &u, field_entry &cur, body_part bp, int scale)
 
bool sees (const tripoint &F, const tripoint &T, int range, int &bresenham_slope) const
 Don't expose the slope adjust outside map functions. More...
 

Friends

class editmap
 
class visitable< map_cursor >
 

Consume items on the map

The functions here consume accessible items / item charges on the map or in vehicles around the player (whose positions is given as origin).

They return a list of copies of the consumed items (with the actually consumed charges in it). The quantity / amount parameter will be reduced by the number of items/charges removed. If all required items could be removed from the map, the quantity/amount will be 0, otherwise it will contain a positive value and the remaining items must be gathered from somewhere else.

enum  iteration_state { ITER_CONTINUE = 0 , ITER_SKIP_SUBMAP , ITER_SKIP_ZLEVEL , ITER_FINISH }
 Enum used by functors in function_over to control execution. More...
 
std::set< tripointsupport_cache_dirty
 
std::vector< submap * > grid
 The list of currently loaded submaps. More...
 
std::vector< std::vector< tripoint > > traplocs
 This vector contains an entry for each trap type, it has therefor the same size as the traplist vector. More...
 
std::vector< tripointfield_furn_locs
 Vector of tripoints containing active field-emitting furniture. More...
 
std::array< std::unique_ptr< level_cache >, OVERMAP_LAYERScaches
 Holds caches for visibility, light, transparency and vehicles. More...
 
std::array< std::unique_ptr< pathfinding_cache >, OVERMAP_LAYERSpathfinding_caches
 
std::set< tripointsubmaps_with_active_items
 Set of submaps that contain active items in absolute coordinates. More...
 
lru_cache< point, char > skew_vision_cache
 Cache of coordinate pairs recently checked for visibility. More...
 
VehicleList last_full_vehicle_list
 Vehicle list doesn't change often, but is pretty expensive. More...
 
bool last_full_vehicle_list_dirty = true
 
visibility_variables visibility_variables_cache
 
cata::optional< std::pair< tripoint, int > > max_populated_zlev = cata::nullopt
 
std::set< vehicle * > dirty_vehicle_list
 
int my_MAPSIZE
 
bool zlevels
 
tripoint abs_sub
 Absolute coordinates of first submap (get_submap_at(0,0)) This is in submap coordinates (see overmapbuffer for explanation). More...
 
std::list< itemuse_amount_square (const tripoint &p, const itype_id &type, int &quantity, const std::function< bool(const item &)> &filter=return_true< item >)
 
std::list< itemuse_amount (const tripoint &origin, int range, const itype_id &type, int &quantity, const std::function< bool(const item &)> &filter=return_true< item >)
 
std::list< itemuse_charges (const tripoint &origin, int range, const itype_id &type, int &quantity, const std::function< bool(const item &)> &filter=return_true< item >, basecamp *bcp=nullptr)
 
std::vector< item * > place_items (const item_group_id &loc, int chance, const tripoint &p1, const tripoint &p2, bool ongrass, const time_point &turn, int magazine=0, int ammo=0)
 Place items from item group in the rectangle f - t. More...
 
std::vector< item * > place_items (const item_group_id &loc, int chance, const point &p1, const point &p2, bool ongrass, const time_point &turn, int magazine=0, int ammo=0)
 
std::vector< item * > put_items_from_loc (const item_group_id &loc, const tripoint &p, const time_point &turn=calendar::start_of_cataclysm)
 Place items from an item group at p. More...
 
std::vector< item * > spawn_items (const tripoint &p, const std::vector< item > &new_items)
 
void spawn_items (const point &p, const std::vector< item > &new_items)
 
void create_anomaly (const tripoint &p, artifact_natural_property prop, bool create_rubble=true)
 
void create_anomaly (const point &cp, artifact_natural_property prop, bool create_rubble=true)
 
void partial_con_set (const tripoint &p, const partial_con &con)
 
void partial_con_remove (const tripoint &p)
 
partial_conpartial_con_at (const tripoint &p)
 
void trap_set (const tripoint &p, const trap_id &type)
 
const traptr_at (const tripoint &p) const
 
bool can_see_trap_at (const tripoint &p, const Character &c) const
 See trap::can_see, which is called for the trap here. More...
 
void disarm_trap (const tripoint &p)
 
void remove_trap (const tripoint &p)
 
const std::vector< tripoint > & get_furn_field_locations () const
 
const std::vector< tripoint > & trap_locations (const trap_id &type) const
 
void create_burnproducts (const tripoint &p, const item &fuel, const units::mass &burned_mass)
 
void process_fields ()
 
void process_fields_in_submap (submap *current_submap, const tripoint &submap_pos)
 
void creature_in_field (Creature &critter)
 Apply field effects to the creature when it's on a square with fields. More...
 
void creature_on_trap (Creature &critter, bool may_avoid=true)
 Apply trap effects to the creature, similar to creature_in_field. More...
 
const fieldfield_at (const tripoint &p) const
 Get the fields that are here. More...
 
fieldfield_at (const tripoint &p)
 Gets fields that are here. More...
 
time_duration get_field_age (const tripoint &p, const field_type_id &type) const
 Get the age of a field entry (field_entry::age), if there is no field of that type, returns -1_turns. More...
 
int get_field_intensity (const tripoint &p, const field_type_id &type) const
 Get the intensity of a field entry (field_entry::intensity), if there is no field of that type, returns 0. More...
 
time_duration mod_field_age (const tripoint &p, const field_type_id &type, const time_duration &offset)
 Increment/decrement age of field entry at point. More...
 
int mod_field_intensity (const tripoint &p, const field_type_id &type, int offset)
 Increment/decrement intensity of field entry at point, creating if not present, removing if intensity becomes 0. More...
 
time_duration set_field_age (const tripoint &p, const field_type_id &type, const time_duration &age, bool isoffset=false)
 Set age of field entry at point. More...
 
int set_field_intensity (const tripoint &p, const field_type_id &type, int new_intensity, bool isoffset=false)
 Set intensity of field entry at point, creating if not present, removing if intensity becomes 0. More...
 
field_entryget_field (const tripoint &p, const field_type_id &type)
 Get field of specific type at point. More...
 
bool dangerous_field_at (const tripoint &p)
 
bool add_field (const tripoint &p, const field_type_id &type_id, int intensity=INT_MAX, const time_duration &age=0_turns, bool hit_player=true)
 Add field entry at point, or set intensity if present. More...
 
void remove_field (const tripoint &p, const field_type_id &field_to_remove)
 Remove field entry at xy, ignored if the field entry is not present. More...
 
void add_splatter (const field_type_id &type, const tripoint &where, int intensity=1)
 
void add_splatter_trail (const field_type_id &type, const tripoint &from, const tripoint &to)
 
void add_splash (const field_type_id &type, const tripoint &center, int radius, int intensity)
 
void propagate_field (const tripoint &center, const field_type_id &type, int amount, int max_intensity=0)
 
void emit_field (const tripoint &pos, const emit_id &src, float mul=1.0f)
 Runs one cycle of emission src which may result in propagation of fields. More...
 
void scent_blockers (std::array< std::array< char, MAPSIZE_X >, MAPSIZE_Y > &scent_transfer, const point &min, const point &max)
 Build the map of scent-resistant tiles. More...
 
computercomputer_at (const tripoint &p)
 
computeradd_computer (const tripoint &p, const std::string &name, int security)
 
void add_camp (const tripoint_abs_omt &omt_pos, const std::string &name)
 
void remove_submap_camp (const tripoint &)
 
basecamp hoist_submap_camp (const tripoint &p)
 
bool point_within_camp (const tripoint &point_check) const
 
bool has_graffiti_at (const tripoint &p) const
 
const std::string & graffiti_at (const tripoint &p) const
 
void set_graffiti (const tripoint &p, const std::string &contents)
 
void delete_graffiti (const tripoint &p)
 
int climb_difficulty (const tripoint &p) const
 Checks 3x3 block centered on p for terrain to climb. More...
 
bool has_floor (const tripoint &p) const
 
bool supports_above (const tripoint &p) const
 Does this tile support vehicles and furniture above it. More...
 
bool has_floor_or_support (const tripoint &p) const
 
void drop_everything (const tripoint &p)
 Handles map objects of given type (not creatures) falling down. More...
 
void drop_furniture (const tripoint &p)
 
void drop_items (const tripoint &p)
 
void drop_vehicle (const tripoint &p)
 
void drop_fields (const tripoint &p)
 
void process_falling ()
 Invoked drop_everything on cached dirty tiles. More...
 
bool is_cornerfloor (const tripoint &p) const
 
void generate (const tripoint &p, const time_point &when)
 
void place_spawns (const mongroup_id &group, int chance, const point &p1, const point &p2, float density, bool individual=false, bool friendly=false, const std::string &name="NONE", int mission_id=-1)
 
void place_gas_pump (const point &p, int charges, const std::string &fuel_type)
 
void place_gas_pump (const point &p, int charges)
 
void place_toilet (const point &p, int charges=6 *4)
 
void place_vending (const point &p, const item_group_id &type, bool reinforced=false)
 
character_id place_npc (const point &p, const string_id< npc_template > &type, bool force=false)
 
void apply_faction_ownership (const point &p1, const point &p2, const faction_id &id)
 
void add_spawn (const mtype_id &type, int count, const tripoint &p, bool friendly=false, int faction_id=-1, int mission_id=-1, const std::string &name="NONE") const
 
void do_vehicle_caching (int z)
 
void build_map_cache (int zlev, bool skip_lightmap=false)
 
void build_obstacle_cache (const tripoint &start, const tripoint &end, float(&obstacle_cache)[MAPSIZE_X][MAPSIZE_Y])
 
vehicleadd_vehicle (const vgroup_id &type, const tripoint &p, units::angle dir, int init_veh_fuel=-1, int init_veh_status=-1, bool merge_wrecks=true)
 
vehicleadd_vehicle (const vgroup_id &type, const point &p, units::angle dir, int init_veh_fuel=-1, int init_veh_status=-1, bool merge_wrecks=true)
 
vehicleadd_vehicle (const vproto_id &type, const tripoint &p, units::angle dir, int init_veh_fuel=-1, int init_veh_status=-1, bool merge_wrecks=true)
 
vehicleadd_vehicle (const vproto_id &type, const point &p, units::angle dir, int init_veh_fuel=-1, int init_veh_status=-1, bool merge_wrecks=true)
 
float light_transparency (const tripoint &p) const
 
lit_level light_at (const tripoint &p) const
 
float ambient_light_at (const tripoint &p) const
 
bool is_transparent (const tripoint &p) const
 Returns whether the tile at p is transparent(you can look past it). More...
 
bool pl_sees (const tripoint &t, int max_range) const
 Whether the player character (g->u) can see the given square (local map coordinates). More...
 
bool pl_line_of_sight (const tripoint &t, int max_range) const
 Uses the map cache to tell if the player could see the given square. More...
 
tripoint get_abs_sub () const
 return abs_sub More...
 
tripoint getabs (const tripoint &p) const
 Translates local (to this map) coordinates of a square to global absolute coordinates. More...
 
point getabs (const point &p) const
 
tripoint getlocal (const tripoint &p) const
 Inverse of getabs. More...
 
point getlocal (const point &p) const
 
virtual bool inbounds (const tripoint &p) const
 
bool inbounds (const point &p) const
 
bool inbounds_z (const int z) const
 
void clip_to_bounds (tripoint &p) const
 Clips the coordinates of p to fit the map bounds. More...
 
void clip_to_bounds (int &x, int &y) const
 
void clip_to_bounds (int &x, int &y, int &z) const
 
int getmapsize () const
 
bool has_zlevels () const
 
void rotate (int turns, bool setpos_safe=false)
 Rotates this map, and all of its contents, by the specified multiple of 90 degrees. More...
 
void spawn_monsters (bool ignore_sight)
 Spawn monsters from submap spawn points and from the overmap. More...
 
void rotten_item_spawn (const item &item, const tripoint &p)
 Checks to see if the item that is rotting away generates a creature when it does. More...
 
void build_outside_cache (int zlev)
 
bool build_floor_cache (int zlev)
 
void build_floor_caches ()
 
void update_suspension_cache (const int &z)
 
bash_results bash_items (const tripoint &p, const bash_params &params)
 
bash_results bash_field (const tripoint &p, const bash_params &params)
 
bash_results bash_ter_success (const tripoint &p, const bash_params &params)
 
bash_results bash_furn_success (const tripoint &p, const bash_params &params)
 
void process_items ()
 
const level_cacheget_cache_ref (int zlev) const
 
const pathfinding_cacheget_pathfinding_cache_ref (int zlev) const
 
void update_pathfinding_cache (int zlev) const
 
void update_visibility_cache (int zlev)
 
const visibility_variablesget_visibility_variables_cache () const
 
void update_submap_active_item_status (const tripoint &p)
 
const std::set< tripoint > & get_submaps_with_active_items () const
 
tripoint_range< tripointpoints_in_rectangle (const tripoint &from, const tripoint &to) const
 
tripoint_range< tripointpoints_in_radius (const tripoint &center, size_t radius, size_t radiusz=0) const
 
tripoint_range< tripointpoints_on_zlevel () const
 Yields a range of all points that are contained in the map and have the z-level of this map (abs_sub). More...
 
tripoint_range< tripointpoints_on_zlevel (int z) const
 Same as above, but uses the specific z-level. More...
 
std::list< item_locationget_active_items_in_radius (const tripoint &center, int radius) const
 
std::list< item_locationget_active_items_in_radius (const tripoint &center, int radius, special_item_type type) const
 
std::list< tripointfind_furnitures_with_flag_in_radius (const tripoint &center, size_t radius, const std::string &flag, size_t radiusz=0)
 returns positions of furnitures with matching flag in the specified radius More...
 
std::list< Creature * > get_creatures_in_radius (const tripoint &center, size_t radius, size_t radiusz=0)
 returns creatures in specified radius More...
 
level_cacheaccess_cache (int zlev)
 
const level_cacheaccess_cache (int zlev) const
 
bool dont_draw_lower_floor (const tripoint &p)
 
void support_dirty (const tripoint &p)
 
void spawn_monsters_submap (const tripoint &gp, bool ignore_sight)
 
void spawn_monsters_submap_group (const tripoint &gp, mongroup &group, bool ignore_sight)
 
fieldget_field (const tripoint &p)
 
submapgetsubmap (size_t grididx) const
 Get the submap pointer with given index in grid, the index must be valid! More...
 
submapget_submap_at (const tripoint &p) const
 Get the submap pointer containing the specified position within the reality bubble. More...
 
submapget_submap_at (const point &p) const
 
submapget_submap_at (const tripoint &p, point &offset_p) const
 Get the submap pointer containing the specified position within the reality bubble. More...
 
submapget_submap_at (const point &p, point &offset_p) const
 
submapget_submap_at_grid (const point &gridp) const
 Get submap pointer in the grid at given grid coordinates. More...
 
submapget_submap_at_grid (const tripoint &gridp) const
 
int calc_max_populated_zlev ()
 Caclulate the greatest populated zlevel in the loaded submaps and save in the level cache. More...
 
void invalidate_max_populated_zlev (int zlev)
 Conditionally invalidates max_pupulated_zlev cache if the submap uniformity change occurs above current max_pupulated_zlev value. More...
 
int move_cost_internal (const furn_t &furniture, const ter_t &terrain, const vehicle *veh, int vpart) const
 Internal versions of public functions to avoid checking same variables multiple times. More...
 
int bash_rating_internal (int str, const furn_t &furniture, const ter_t &terrain, bool allow_floor, const vehicle *veh, int part) const
 
bool draw_maptile (const catacurses::window &w, const tripoint &p, const maptile &tile, const drawsq_params &params) const
 Internal version of the drawsq. More...
 
void draw_from_above (const catacurses::window &w, const tripoint &p, const maptile &tile, const drawsq_params &params) const
 Draws the tile as seen from above. More...
 
int determine_wall_corner (const tripoint &p) const
 
void apply_light_source (const tripoint &p, float luminance)
 
void add_light_source (const tripoint &p, float luminance)
 
void apply_directional_light (const tripoint &p, int direction, float luminance)
 
void apply_light_arc (const tripoint &p, units::angle, float luminance, units::angle wideangle=30_degrees)
 
void apply_light_ray (bool lit[MAPSIZE_X][MAPSIZE_Y], const tripoint &s, const tripoint &e, float luminance)
 
void add_light_from_items (const tripoint &p, item_stack::iterator begin, item_stack::iterator end)
 
std::unique_ptr< vehicleadd_vehicle_to_map (std::unique_ptr< vehicle > veh, bool merge_wrecks)
 Takes a vehicle already created with new and attempts to place it on the map, checking for collisions. More...
 
ter_id get_roof (const tripoint &p, bool allow_air) const
 
void process_items_in_submap (submap &current_submap, const tripoint &gridp)
 
void process_items_in_vehicles (submap &current_submap)
 
void process_items_in_vehicle (vehicle &cur_veh, submap &current_submap)
 
template<typename Functor >
void function_over (const tripoint &start, const tripoint &end, Functor fun) const
 Runs a functor over given submaps over submaps in the area, getting next submap only when the current one "runs out" rather than every time. More...
 
level_cacheget_cache (int zlev) const
 
pathfinding_cacheget_pathfinding_cache (int zlev) const
 
void saven (const tripoint &grid)
 
void loadn (const tripoint &grid, bool update_vehicles)
 
void loadn (const point &grid, bool update_vehicles)
 
void actualize (const tripoint &grid)
 Fast forward a submap that has just been loading into this map. More...
 
void add_roofs (const tripoint &grid)
 Hacks in missing roofs. More...
 
template<typename Container >
void remove_rotten_items (Container &items, const tripoint &p)
 Go through the list of items, update their rotten status and remove items that have rotten away completely. More...
 
void fill_funnels (const tripoint &p, const time_point &since)
 Try to fill funnel based items here. More...
 
void grow_plant (const tripoint &p)
 Try to grow a harvestable plant to the next stage(s). More...
 
void restock_fruits (const tripoint &p, const time_duration &time_since_last_actualize)
 Try to grow fruits on static plants (not planted by the player) More...
 
void produce_sap (const tripoint &p, const time_duration &time_since_last_actualize)
 Produce sap on tapped maple trees. More...
 
void rad_scorch (const tripoint &p, const time_duration &time_since_last_actualize)
 Radiation-related plant (and fungus?) death. More...
 
void decay_cosmetic_fields (const tripoint &p, const time_duration &time_since_last_actualize)
 
void player_in_field (player &u)
 
void monster_in_field (monster &z)
 
void shift_traps (const tripoint &shift)
 As part of the map shifting, this shifts the trap locations stored in traplocs. More...
 
void copy_grid (const tripoint &to, const tripoint &from)
 
void draw_map (mapgendata &dat)
 
void draw_office_tower (mapgendata &dat)
 
void draw_lab (mapgendata &dat)
 
void draw_temple (mapgendata &dat)
 
void draw_mine (mapgendata &dat)
 
void draw_anthill (mapgendata &dat)
 
void draw_slimepit (mapgendata &dat)
 
void draw_triffid (mapgendata &dat)
 
void draw_connections (mapgendata &dat)
 
bool build_transparency_cache (int zlev)
 
bool build_vision_transparency_cache (int zlev)
 
void build_sunlight_cache (int pzlev)
 
void generate_lightmap (int zlev)
 
void build_seen_cache (const tripoint &origin, int target_z)
 Calculates the Field Of View for the provided map from the given x, y coordinates. More...
 
void apply_character_light (Character &p)
 
void set_abs_sub (const tripoint &p)
 Sets abs_sub, see there. More...
 
size_t get_nonant (const tripoint &gridp) const
 Get the index of a submap pointer in the grid given by grid coordinates. More...
 
size_t get_nonant (const point &gridp) const
 
void setsubmap (size_t grididx, submap *smap)
 Set the submap pointer in grid at the give index. More...
 

Detailed Description

Manage and cache data about a part of the map.

Despite the name, this class isn't actually responsible for managing the map as a whole. For that function, see mapbuffer. Instead, this class loads a part of the mapbuffer into a cache, and adds certain temporary information such as lighting calculations to it.

To understand the following descriptions better, you should also read Map Management

The map coordinates always start at (0, 0) for the top-left and end at (map_width-1, map_height-1) for the bottom-right.

The actual map data is stored in submap instances. These instances are managed by mapbuffer. References to the currently active submaps are stored in map::grid: 0 1 2 3 4 5 6 7 8 In this example, the top-right submap would be at grid[2].

When the player moves between submaps, the whole map is shifted, so that if the player moves one submap to the right, (0, 0) now points to a tile one submap to the right from before

Definition at line 388 of file map.h.

Member Enumeration Documentation

◆ iteration_state

enum map::iteration_state
private

Enum used by functors in function_over to control execution.

Enumerator
ITER_CONTINUE 
ITER_SKIP_SUBMAP 
ITER_SKIP_ZLEVEL 
ITER_FINISH 

Definition at line 1967 of file map.h.

1967 {
1968 ITER_CONTINUE = 0, // Keep iterating
1969 ITER_SKIP_SUBMAP, // Skip the rest of this submap
1970 ITER_SKIP_ZLEVEL, // Skip the rest of this z-level
1971 ITER_FINISH // End iteration
1972 };
@ ITER_SKIP_ZLEVEL
Definition: map.h:1970
@ ITER_SKIP_SUBMAP
Definition: map.h:1969
@ ITER_CONTINUE
Definition: map.h:1968
@ ITER_FINISH
Definition: map.h:1971

Constructor & Destructor Documentation

◆ map() [1/2]

map::map ( int  mapsize = MAPSIZE,
bool  zlev = false 
)

Definition at line 174 of file map.cpp.

175{
176 my_MAPSIZE = mapsize;
177 zlevels = zlev;
178 if( zlevels ) {
179 grid.resize( static_cast<size_t>( my_MAPSIZE * my_MAPSIZE * OVERMAP_LAYERS ), nullptr );
180 } else {
181 grid.resize( static_cast<size_t>( my_MAPSIZE * my_MAPSIZE ), nullptr );
182 }
183
184 for( auto &ptr : caches ) {
185 ptr = std::make_unique<level_cache>();
186 }
187
188 for( auto &ptr : pathfinding_caches ) {
189 ptr = std::make_unique<pathfinding_cache>();
190 }
191
192 dbg( DL::Info ) << "map::map(): my_MAPSIZE: " << my_MAPSIZE << " z-levels enabled:" << zlevels;
193 traplocs.resize( trap::count() );
194}
std::vector< std::vector< tripoint > > traplocs
This vector contains an entry for each trap type, it has therefor the same size as the traplist vecto...
Definition: map.h:1999
std::array< std::unique_ptr< pathfinding_cache >, OVERMAP_LAYERS > pathfinding_caches
Definition: map.h:2009
std::vector< submap * > grid
The list of currently loaded submaps.
Definition: map.h:1992
int my_MAPSIZE
Definition: map.h:1824
bool zlevels
Definition: map.h:1825
std::array< std::unique_ptr< level_cache >, OVERMAP_LAYERS > caches
Holds caches for visibility, light, transparency and vehicles.
Definition: map.h:2007
@ Info
Information (default: enabled).
const void * ptr(const T *p)
\rst Converts p to const void* for pointer formatting.
static constexpr int OVERMAP_LAYERS
#define dbg(x)
Definition: map.cpp:138
static size_t count()
Definition: trap.cpp:95

References caches, trap::count(), dbg, grid, Info, my_MAPSIZE, OVERMAP_LAYERS, pathfinding_caches, ptr(), traplocs, and zlevels.

Referenced by check_submap_active_item_consistency().

◆ map() [2/2]

map::map ( bool  zlev)
inlineexplicit

Definition at line 396 of file map.h.

396: map( MAPSIZE, zlev ) { }
map(int mapsize=MAPSIZE, bool zlev=false)
Definition: map.cpp:174
static constexpr int MAPSIZE

◆ ~map()

map::~map ( )
virtualdefault

Member Function Documentation

◆ access_cache() [1/2]

level_cache & map::access_cache ( int  zlev)

Definition at line 8705 of file map.cpp.

8706{
8707 if( zlev >= -OVERMAP_DEPTH && zlev <= OVERMAP_HEIGHT ) {
8708 return *caches[zlev + OVERMAP_DEPTH];
8709 }
8710
8711 debugmsg( "access_cache called with invalid z-level: %d", zlev );
8712 return nullcache;
8713}
#define debugmsg(...)
Debug message of level DL::Error and class DC::DebugMsg, also includes the source file name and line,...
Definition: debug.h:74
static constexpr int OVERMAP_HEIGHT
static constexpr int OVERMAP_DEPTH
static level_cache nullcache
Definition: map.cpp:142

References caches, debugmsg, nullcache, OVERMAP_DEPTH, and OVERMAP_HEIGHT.

Referenced by get_known_connections(), game::place_player_overmap(), process_items(), explosion_handler::shrapnel(), scent_map::update(), and game::vertical_shift().

◆ access_cache() [2/2]

const level_cache & map::access_cache ( int  zlev) const

Definition at line 8715 of file map.cpp.

8716{
8717 if( zlev >= -OVERMAP_DEPTH && zlev <= OVERMAP_HEIGHT ) {
8718 return *caches[zlev + OVERMAP_DEPTH];
8719 }
8720
8721 debugmsg( "access_cache called with invalid z-level: %d", zlev );
8722 return nullcache;
8723}

References caches, debugmsg, nullcache, OVERMAP_DEPTH, and OVERMAP_HEIGHT.

◆ accessible_items()

bool map::accessible_items ( const tripoint t) const

Check whether the player can access the items located .

Certain furniture/terrain may prevent that (e.g. a locked safe).

Definition at line 6555 of file map.cpp.

6556{
6557 return !has_flag( "SEALED", t ) || has_flag( "LIQUIDCONT", t );
6558}
bool has_flag(const std::string &flag, const tripoint &p) const
Definition: map.cpp:2293

References has_flag().

Referenced by basecamp::form_crafting_inventory(), inventory::form_from_map(), player::get_eligible_containers_for_crafting(), has_clear_path_to_pickup_items(), try_fuel_fire(), and use_charges().

◆ actualize()

void map::actualize ( const tripoint grid)
protected

Fast forward a submap that has just been loading into this map.

This is used to rot and remove rotten items, grow plants, fill funnels etc.

Definition at line 7406 of file map.cpp.

7407{
7408 submap *const tmpsub = get_submap_at_grid( grid );
7409 if( tmpsub == nullptr ) {
7410 debugmsg( "Actualize called on null submap (%d,%d,%d)", grid.x, grid.y, grid.z );
7411 return;
7412 }
7413
7414 const time_duration time_since_last_actualize = calendar::turn - tmpsub->last_touched;
7415 const bool do_funnels = ( grid.z >= 0 );
7416
7417 // check spoiled stuff, and fill up funnels while we're at it
7418 for( int x = 0; x < SEEX; x++ ) {
7419 for( int y = 0; y < SEEY; y++ ) {
7420 const tripoint pnt = sm_to_ms_copy( grid ) + point( x, y );
7421 const point p( x, y );
7422 const auto &furn = this->furn( pnt ).obj();
7423 if( furn.has_flag( "EMITTER" ) ) {
7424 field_furn_locs.push_back( pnt );
7425 }
7426 // plants contain a seed item which must not be removed under any circumstances
7427 if( !furn.has_flag( "DONT_REMOVE_ROTTEN" ) ) {
7428 remove_rotten_items( tmpsub->get_items( { x, y } ), pnt );
7429 }
7430
7431 const auto trap_here = tmpsub->get_trap( p );
7432 if( trap_here != tr_null ) {
7433 traplocs[trap_here.to_i()].push_back( pnt );
7434 }
7435 const ter_t &ter = tmpsub->get_ter( p ).obj();
7436 if( ter.trap != tr_null && ter.trap != tr_ledge ) {
7437 traplocs[ter.trap.to_i()].push_back( pnt );
7438 }
7439
7440 if( do_funnels ) {
7441 fill_funnels( pnt, tmpsub->last_touched );
7442 }
7443
7444 grow_plant( pnt );
7445
7446 restock_fruits( pnt, time_since_last_actualize );
7447
7448 produce_sap( pnt, time_since_last_actualize );
7449
7450 rad_scorch( pnt, time_since_last_actualize );
7451
7452 decay_cosmetic_fields( pnt, time_since_last_actualize );
7453 }
7454 }
7455
7456 // the last time we touched the submap, is right now.
7457 tmpsub->last_touched = calendar::turn;
7458}
const T & obj() const
Definition: ammo_effect.cpp:26
int to_i() const
Returns the identifier as plain int.
Definition: int_id.h:84
void remove_rotten_items(Container &items, const tripoint &p)
Go through the list of items, update their rotten status and remove items that have rotten away compl...
Definition: map.cpp:7089
void rad_scorch(const tripoint &p, const time_duration &time_since_last_actualize)
Radiation-related plant (and fungus?) death.
Definition: map.cpp:7340
void fill_funnels(const tripoint &p, const time_point &since)
Try to fill funnel based items here.
Definition: map.cpp:7128
std::vector< tripoint > field_furn_locs
Vector of tripoints containing active field-emitting furniture.
Definition: map.h:2003
void decay_cosmetic_fields(const tripoint &p, const time_duration &time_since_last_actualize)
Definition: map.cpp:7386
void restock_fruits(const tripoint &p, const time_duration &time_since_last_actualize)
Try to grow fruits on static plants (not planted by the player)
Definition: map.cpp:7229
ter_id ter(const tripoint &p) const
Definition: map.cpp:1498
void grow_plant(const tripoint &p)
Try to grow a harvestable plant to the next stage(s).
Definition: map.cpp:7151
submap * get_submap_at_grid(const point &gridp) const
Get submap pointer in the grid at given grid coordinates.
Definition: map.h:1870
void produce_sap(const tripoint &p, const time_duration &time_since_last_actualize)
Produce sap on tapped maple trees.
Definition: map.cpp:7243
furn_id furn(const tripoint &p) const
Definition: map.cpp:1348
Definition: submap.h:65
time_point last_touched
Definition: submap.h:240
trap_id get_trap(const point &p) const
Definition: submap.h:73
ter_id get_ter(const point &p) const
Definition: submap.h:99
cata::colony< item > & get_items(const point &p)
Definition: submap.h:161
A duration defined as a number of specific time units.
Definition: calendar.h:180
point sm_to_ms_copy(const point &p)
static constexpr int SEEX
static constexpr int SEEY
static const trap_str_id tr_ledge("tr_ledge")
time_point turn
Definition: calendar.cpp:36
Definition: point.h:35
Definition: mapdata.h:457
trap_id tr_null
Definition: trap.cpp:276

References debugmsg, decay_cosmetic_fields(), field_furn_locs, fill_funnels(), furn(), submap::get_items(), get_submap_at_grid(), submap::get_ter(), submap::get_trap(), grid, grow_plant(), submap::last_touched, int_id< T >::obj(), produce_sap(), rad_scorch(), remove_rotten_items(), restock_fruits(), SEEX, SEEY, sm_to_ms_copy(), ter(), int_id< T >::to_i(), tr_ledge, tr_null, traplocs, and calendar::turn.

Referenced by loadn().

◆ add_camp()

void map::add_camp ( const tripoint_abs_omt omt_pos,
const std::string &  name 
)

Definition at line 5579 of file map.cpp.

5580{
5581 basecamp temp_camp = basecamp( name, omt_pos );
5582 overmap_buffer.add_camp( temp_camp );
5583 g->u.camps.insert( omt_pos );
5584 g->validate_camps();
5585}
std::string name(const tripoint &p)
Definition: map.cpp:1325
void add_camp(const basecamp &camp)
Add Basecamp to overmapbuffer.
std::unique_ptr< game > g
Definition: game.cpp:273
overmapbuffer overmap_buffer

References overmapbuffer::add_camp(), g, name(), and overmap_buffer.

Referenced by get_basecamp().

◆ add_computer()

computer * map::add_computer ( const tripoint p,
const std::string &  name,
int  security 
)

Definition at line 5787 of file mapgen.cpp.

5788{
5789 // TODO: Turn this off?
5790 ter_set( p, t_console );
5791 point l;
5792 submap *const place_on_submap = get_submap_at( p, l );
5793 place_on_submap->set_computer( l, computer( name, security ) );
5794 return place_on_submap->get_computer( l );
5795}
bool ter_set(const tripoint &p, const ter_id &new_terrain)
Definition: map.cpp:1639
submap * get_submap_at(const tripoint &p) const
Get the submap pointer containing the specified position within the reality bubble.
Definition: map.cpp:8302
void set_computer(const point &p, const computer &c)
Definition: submap.cpp:203
const computer * get_computer(const point &p) const
Definition: submap.cpp:177
ter_id t_console
Definition: mapdata.cpp:704

References submap::get_computer(), get_submap_at(), name(), submap::set_computer(), t_console, and ter_set().

Referenced by jmapgen_computer::apply(), create_lab_consoles(), draw_lab(), mission_start::place_npc_software(), and science_room().

◆ add_corpse()

void map::add_corpse ( const tripoint p)

Definition at line 8446 of file map.cpp.

8447{
8448 item body;
8449
8450 const bool isReviveSpecial = one_in( 10 );
8451
8452 if( !isReviveSpecial ) {
8453 body = item::make_corpse();
8454 } else {
8455 body = item::make_corpse( mon_zombie );
8456 body.set_flag( "REVIVE_SPECIAL" );
8457 }
8458
8459 put_items_from_loc( item_group_id( "default_zombie_clothes" ), p );
8460 if( one_in( 3 ) ) {
8461 put_items_from_loc( item_group_id( "default_zombie_items" ), p );
8462 }
8463
8464 add_item_or_charges( p, body );
8465}
Definition: item.h:177
static item make_corpse(const mtype_id &mt=string_id< mtype >::NULL_ID(), time_point turn=calendar::turn, const std::string &name="", int upgrade_time=-1)
Make a corpse of the given monster type.
Definition: item.cpp:507
item & set_flag(const std::string &flag)
Idempotent filter setting an item specific flag.
Definition: item.cpp:5242
item & add_item_or_charges(const tripoint &pos, item obj, bool overflow=true)
Adds an item to map tile or stacks charges.
Definition: map.cpp:4224
std::vector< item * > put_items_from_loc(const item_group_id &loc, const tripoint &p, const time_point &turn=calendar::start_of_cataclysm)
Place items from an item group at p.
Definition: mapgen.cpp:5575
static const mtype_id mon_zombie("mon_zombie")
bool one_in(int chance)
Definition: rng.cpp:65
string_id< Item_group > item_group_id
Definition: type_id.h:77

References add_item_or_charges(), item::make_corpse(), mon_zombie, one_in(), put_items_from_loc(), and item::set_flag().

Referenced by add_corpse(), MapExtras::mx_looters(), MapExtras::mx_mayhem(), and MapExtras::mx_minefield().

◆ add_field()

bool map::add_field ( const tripoint p,
const field_type_id type_id,
int  intensity = INT_MAX,
const time_duration age = 0_turns,
bool  hit_player = true 
)

Add field entry at point, or set intensity if present.

Returns
false if the field could not be created (out of bounds), otherwise true.

Definition at line 5396 of file map.cpp.

5398{
5399 if( !inbounds( p ) ) {
5400 return false;
5401 }
5402
5403 if( !type_id ) {
5404 debugmsg( "Tried to add null field" );
5405 return false;
5406 }
5407
5408 const field_type &fd_type = *type_id;
5409 intensity = std::min( intensity, fd_type.get_max_intensity() );
5410 if( intensity <= 0 ) {
5411 return false;
5412 }
5413
5414 point l;
5415 submap *const current_submap = get_submap_at( p, l );
5416 current_submap->is_uniform = false;
5418
5419 if( current_submap->get_field( l ).add_field( type_id, intensity, age ) ) {
5420 //Only adding it to the count if it doesn't exist.
5421 if( !current_submap->field_count++ ) {
5422 get_cache( p.z ).field_cache.set( static_cast<size_t>( p.x / SEEX + ( (
5423 p.y / SEEX ) * MAPSIZE ) ) );
5424 }
5425 }
5426
5427 if( hit_player ) {
5428 Character &player_character = get_player_character();
5429 if( g != nullptr && this == &get_map() && p == player_character.pos() ) {
5430 //Hit the player with the field if it spawned on top of them.
5431 creature_in_field( player_character );
5432 }
5433 }
5434
5435 // Dirty the transparency cache now that field processing doesn't always do it
5436 if( fd_type.dirty_transparency_cache || !fd_type.is_transparent() ) {
5439 }
5440
5441 if( fd_type.is_dangerous() ) {
5443 }
5444
5445 // Ensure blood type fields don't hang in the air
5446 if( zlevels && fd_type.accelerated_decay ) {
5447 support_dirty( p );
5448 }
5449
5450 return true;
5451}
Character & get_player_character()
Definition: character.cpp:387
const tripoint & pos() const override
Definition: character.cpp:714
bool add_field(const field_type_id &field_type_to_add, int new_intensity=1, const time_duration &new_age=0_turns)
Inserts the given field_type_id into the field list for a given tile if it does not already exist.
Definition: field.cpp:190
void set_transparency_cache_dirty(const int zlev)
Sets a dirty flag on the a given cache.
Definition: map.h:410
level_cache & get_cache(int zlev) const
Definition: map.h:2027
virtual bool inbounds(const tripoint &p) const
Definition: map.cpp:7756
void set_pathfinding_cache_dirty(int zlev)
Definition: map.cpp:8761
void creature_in_field(Creature &critter)
Apply field effects to the creature when it's on a square with fields.
Definition: map_field.cpp:1563
void support_dirty(const tripoint &p)
Definition: map.cpp:2267
void invalidate_max_populated_zlev(int zlev)
Conditionally invalidates max_pupulated_zlev cache if the submap uniformity change occurs above curre...
Definition: map.cpp:8954
void set_seen_cache_dirty(const tripoint change_location)
Definition: map.h:426
int field_count
Definition: submap.h:239
field & get_field(const point &p)
Definition: submap.h:170
bool is_uniform
Definition: submap.h:233
map & get_map()
Definition: map.cpp:146
bool accelerated_decay
Definition: field_type.h:179
bool is_transparent() const
Definition: field_type.h:262
bool dirty_transparency_cache
Definition: field_type.h:161
bool is_dangerous() const
Definition: field_type.h:256
int get_max_intensity() const
Definition: field_type.h:268
std::bitset< MAPSIZE *MAPSIZE > field_cache
Definition: map.h:357
int y
Definition: point.h:151
int z
Definition: point.h:152
int x
Definition: point.h:150

References field_type::accelerated_decay, field::add_field(), creature_in_field(), debugmsg, field_type::dirty_transparency_cache, level_cache::field_cache, submap::field_count, g, get_cache(), submap::get_field(), get_map(), field_type::get_max_intensity(), get_player_character(), get_submap_at(), inbounds(), invalidate_max_populated_zlev(), field_type::is_dangerous(), field_type::is_transparent(), submap::is_uniform, MAPSIZE, Character::pos(), SEEX, set_pathfinding_cache_dirty(), set_seen_cache_dirty(), set_transparency_cache_dirty(), support_dirty(), tripoint::x, tripoint::y, tripoint::z, and zlevels.

Referenced by Character::activate_bionic(), jmapgen_field::apply(), apply_ammo_effects(), Character::blossoms(), mattack::boomer(), mattack::boomer_glow(), start_location::burn(), create_anomaly(), spell::create_field(), create_hot_air(), explosion_handler::do_blast(), draw_lab(), draw_mine(), draw_temple(), draw_triffid(), drop_fields(), editmap::edit_fld(), iexamine::fireplace(), mattack::flame(), gas_spread_to(), hit_with_fire(), madd_field(), MapExtras::mx_casings(), MapExtras::mx_corpses(), MapExtras::mx_drugdeal(), MapExtras::mx_looters(), MapExtras::mx_mayhem(), MapExtras::mx_minefield(), MapExtras::mx_portal_in(), MapExtras::mx_roadblock(), MapExtras::mx_spider(), game::process_artifact(), process_fields_in_submap(), explosion_handler::explosion_funcs::resonance_cascade(), mattack::riotbot(), set_field_intensity(), shoot(), explosion_iuse::trigger_explosion(), and consume_drug_iuse::use().

◆ add_item() [1/2]

void map::add_item ( const point p,
item  new_item 
)
inline

Definition at line 1307 of file map.h.

1307 {
1308 add_item( tripoint( p, abs_sub.z ), new_item );
1309 }
tripoint abs_sub
Absolute coordinates of first submap (get_submap_at(0,0)) This is in submap coordinates (see overmapb...
Definition: map.h:1835
item & add_item(const tripoint &p, item new_item)
Place an item on the map, despite the parameter name, this is not necessarily a new item.
Definition: map.cpp:4324

References abs_sub, add_item(), and tripoint::z.

◆ add_item() [2/2]

item & map::add_item ( const tripoint p,
item  new_item 
)

Place an item on the map, despite the parameter name, this is not necessarily a new item.

WARNING: does -not- check volume or stack charges. player functions (drop etc) should use map::add_item_or_charges

Returns
The item that got added, or nulitem.

Definition at line 4324 of file map.cpp.

4325{
4326 if( !inbounds( p ) ) {
4327 return null_item_reference();
4328 }
4329 point l;
4330 submap *const current_submap = get_submap_at( p, l );
4331
4332 // Process foods when they are added to the map, here instead of add_item_at()
4333 // to avoid double processing food and corpses during active item processing.
4334 if( new_item.is_food() ) {
4335 new_item.process( nullptr, p, false );
4336 }
4337
4338 if( new_item.made_of( LIQUID ) && has_flag( "SWIMMABLE", p ) ) {
4339 return null_item_reference();
4340 }
4341
4342 if( has_flag( "DESTROY_ITEM", p ) ) {
4343 return null_item_reference();
4344 }
4345
4346 if( new_item.has_flag( "ACT_IN_FIRE" ) && get_field( p, fd_fire ) != nullptr ) {
4347 if( new_item.has_flag( "BOMB" ) && new_item.is_transformable() ) {
4348 //Convert a bomb item into its transformable version, e.g. incendiary grenade -> active incendiary grenade
4349 new_item.convert( dynamic_cast<const iuse_transform *>
4350 ( new_item.type->get_use( "transform" )->get_actor_ptr() )->target );
4351 }
4352 new_item.active = true;
4353 }
4354
4355 if( new_item.is_map() && !new_item.has_var( "reveal_map_center_omt" ) ) {
4356 new_item.set_var( "reveal_map_center_omt", ms_to_omt_copy( getabs( p ) ) );
4357 }
4358
4359 current_submap->is_uniform = false;
4361
4362 current_submap->update_lum_add( l, new_item );
4363
4364 const map_stack::iterator new_pos = current_submap->get_items( l ).insert( new_item );
4365 if( new_item.needs_processing() ) {
4366 if( current_submap->active_items.empty() ) {
4367 submaps_with_active_items.insert( tripoint( abs_sub.x + p.x / SEEX, abs_sub.y + p.y / SEEY, p.z ) );
4368 }
4369 current_submap->active_items.add( *new_pos, l );
4370 }
4371
4372 return *new_pos;
4373}
void add(item &it, point location)
Adds the reference to the cache.
bool empty() const
Returns true if the cache is empty.
bool is_transformable() const
Definition: item.cpp:6829
bool needs_processing() const
Whether the item should be processed (by calling process).
Definition: item.cpp:8793
bool active
Definition: item.h:2234
bool process(player *carrier, const tripoint &pos, bool activate, float insulation=1, temperature_flag flag=temperature_flag::TEMP_NORMAL)
This is called once each turn.
Definition: item.cpp:9447
const std::vector< material_id > & made_of() const
The ids of all the materials this is made of.
Definition: item.cpp:6284
item & convert(const itype_id &new_type)
Filter converting this instance to another type preserving all other aspects.
Definition: item.cpp:533
bool has_var(const std::string &name) const
Whether the variable is defined at all.
Definition: item.cpp:1070
void set_var(const std::string &name, int value)
Definition: item.cpp:995
bool has_flag(const std::string &flag) const
Definition: item.cpp:5213
bool is_map() const
Definition: item.cpp:6585
bool is_food() const
Definition: item.cpp:6463
const itype * type
Definition: item.h:2157
Transform an item into a specific type.
Definition: iuse_actor.h:52
itype_id target
type of the resulting item
Definition: iuse_actor.h:58
std::set< tripoint > submaps_with_active_items
Set of submaps that contain active items in absolute coordinates.
Definition: map.h:2013
field_entry * get_field(const tripoint &p, const field_type_id &type)
Get field of specific type at point.
Definition: map.cpp:5373
tripoint getabs(const tripoint &p) const
Translates local (to this map) coordinates of a square to global absolute coordinates.
Definition: map.cpp:8261
void update_lum_add(const point &p, const item &i)
Definition: submap.h:130
active_item_cache active_items
Definition: submap.h:237
point ms_to_omt_copy(const point &p)
@ LIQUID
Definition: enums.h:175
field_type_id fd_fire
Definition: field_type.cpp:345
item & null_item_reference()
Returns a reference to a null item (see item::is_null).
Definition: item.cpp:322
const use_function * get_use(const std::string &iuse_name) const
Definition: itype.cpp:91
iuse_actor * get_actor_ptr()
Definition: iuse.h:314

References abs_sub, item::active, submap::active_items, active_item_cache::add(), item::convert(), active_item_cache::empty(), fd_fire, use_function::get_actor_ptr(), get_field(), submap::get_items(), get_submap_at(), itype::get_use(), getabs(), item::has_flag(), has_flag(), item::has_var(), inbounds(), invalidate_max_populated_zlev(), item::is_food(), item::is_map(), item::is_transformable(), submap::is_uniform, LIQUID, item::made_of(), ms_to_omt_copy(), item::needs_processing(), null_item_reference(), item::process(), SEEX, SEEY, item::set_var(), submaps_with_active_items, iuse_transform::target, item::type, submap::update_lum_add(), tripoint::x, tripoint::y, and tripoint::z.

Referenced by add_item(), add_item_or_charges(), iexamine::arcfurnace_empty(), iexamine::arcfurnace_full(), draw_mine(), extract_or_wreck_cbms(), iexamine::fvat_empty(), iexamine::fvat_full(), iexamine::keg(), iexamine::kiln_empty(), iexamine::kiln_full(), mill_activate(), mill_load_food(), Character::perform_uninstall(), place_gas_pump(), place_toilet(), iexamine::pour_into_keg(), iexamine::reload_furniture(), smoker_activate(), smoker_load_food(), Character::uninstall_bionic(), and avatar_action::wield().

◆ add_item_or_charges() [1/2]

item & map::add_item_or_charges ( const point p,
item  obj,
bool  overflow = true 
)
inline

Definition at line 1295 of file map.h.

1295 {
1296 return add_item_or_charges( tripoint( p, abs_sub.z ), obj, overflow );
1297 }

References abs_sub, add_item_or_charges(), and tripoint::z.

◆ add_item_or_charges() [2/2]

item & map::add_item_or_charges ( const tripoint pos,
item  obj,
bool  overflow = true 
)

Adds an item to map tile or stacks charges.

Parameters
posWhere to add item
objItem to add
overflowif destination is full attempt to drop on adjacent tiles
Returns
reference to dropped (and possibly stacked) item or null item on failure
Warning
function is relatively expensive and meant for user initiated actions, not mapgen

Definition at line 4224 of file map.cpp.

4225{
4226 // Checks if item would not be destroyed if added to this tile
4227 auto valid_tile = [&]( const tripoint & e ) {
4228 if( !inbounds( e ) ) {
4229 // should never happen
4230 debugmsg( "add_item_or_charges: %s is out of bounds (adding item '%s' [%d])",
4231 e.to_string(), obj.typeId().c_str(), obj.charges );
4232 return false;
4233 }
4234
4235 // Some tiles destroy items (e.g. lava)
4236 if( has_flag( "DESTROY_ITEM", e ) ) {
4237 return false;
4238 }
4239
4240 // Cannot drop liquids into tiles that are comprised of liquid
4241 if( obj.made_of( LIQUID ) && has_flag( "SWIMMABLE", e ) ) {
4242 return false;
4243 }
4244
4245 return true;
4246 };
4247
4248 // Checks if sufficient space at tile to add item
4249 auto valid_limits = [&]( const tripoint & e ) {
4250 return obj.volume() <= free_volume( e ) && i_at( e ).size() < MAX_ITEM_IN_SQUARE;
4251 };
4252
4253 // Performs the actual insertion of the object onto the map
4254 auto place_item = [&]( const tripoint & tile ) -> item& {
4255 if( obj.count_by_charges() )
4256 {
4257 for( auto &e : i_at( tile ) ) {
4258 if( e.merge_charges( obj ) ) {
4259 return e;
4260 }
4261 }
4262 }
4263
4264 support_dirty( tile );
4265 return add_item( tile, obj );
4266 };
4267
4268 // Some items never exist on map as a discrete item (must be contained by another item)
4269 if( obj.has_flag( "NO_DROP" ) ) {
4270 return null_item_reference();
4271 }
4272
4273 // If intended drop tile destroys the item then we don't attempt to overflow
4274 if( !valid_tile( pos ) ) {
4275 return null_item_reference();
4276 }
4277
4278 if( ( !has_flag( "NOITEM", pos ) || ( has_flag( "LIQUIDCONT", pos ) && obj.made_of( LIQUID ) ) )
4279 && valid_limits( pos ) ) {
4280 // Pass map into on_drop, because this map may not be the global map object (in mapgen, for instance).
4281 if( obj.made_of( LIQUID ) || !obj.has_flag( "DROP_ACTION_ONLY_IF_LIQUID" ) ) {
4282 if( obj.on_drop( pos, *this ) ) {
4283 return null_item_reference();
4284 }
4285
4286 }
4287 // If tile can contain items place here...
4288 return place_item( pos );
4289
4290 } else if( overflow ) {
4291 // ...otherwise try to overflow to adjacent tiles (if permitted)
4292 const int max_dist = 2;
4293 std::vector<tripoint> tiles = closest_points_first( pos, max_dist );
4294 tiles.erase( tiles.begin() ); // we already tried this position
4295 const int max_path_length = 4 * max_dist;
4296 const pathfinding_settings setting( 0, max_dist, max_path_length, 0, false, true, false, false,
4297 false );
4298 for( const tripoint &e : tiles ) {
4299 if( !inbounds( e ) ) {
4300 continue;
4301 }
4302 //must be a path to the target tile
4303 if( route( pos, e, setting ).empty() ) {
4304 continue;
4305 }
4306 if( obj.made_of( LIQUID ) || !obj.has_flag( "DROP_ACTION_ONLY_IF_LIQUID" ) ) {
4307 if( obj.on_drop( e, *this ) ) {
4308 return null_item_reference();
4309 }
4310 }
4311
4312 if( !valid_tile( e ) || !valid_limits( e ) ||
4313 has_flag( "NOITEM", e ) || has_flag( "SEALED", e ) ) {
4314 continue;
4315 }
4316 return place_item( e );
4317 }
4318 }
4319
4320 // failed due to lack of space at target tile (+/- overflow tiles)
4321 return null_item_reference();
4322}
size_t size() const
Definition: item_stack.cpp:10
bool count_by_charges() const
Definition: item.cpp:5876
units::volume volume(bool integral=false) const
Total volume of an item accounting for all contained/integrated items NOTE: Result is rounded up to n...
Definition: item.cpp:5012
int charges
Definition: item.h:2196
bool on_drop(const tripoint &pos)
Invokes item type's itype::drop_action.
Definition: item.cpp:9835
const itype_id & typeId() const
return the unique identifier of the items underlying type
Definition: item.cpp:8217
map_stack i_at(const tripoint &p)
Definition: map.cpp:4079
units::volume free_volume(const tripoint &p)
Definition: map.cpp:4219
std::vector< tripoint > route(const tripoint &f, const tripoint &t, const pathfinding_settings &settings, const std::set< tripoint > &pre_closed={{ }}) const
Calculate the best path using A*.
const char * c_str() const
Interface to the plain C-string of the id.
Definition: string_id.h:247
std::vector< coords::coord_point< Point, Origin, Scale > > closest_points_first(const coords::coord_point< Point, Origin, Scale > &loc, int min_dist, int max_dist)
Definition: coordinates.h:596
static constexpr int MAX_ITEM_IN_SQUARE

References add_item(), string_id< T >::c_str(), item::charges, closest_points_first(), item::count_by_charges(), debugmsg, free_volume(), item::has_flag(), has_flag(), i_at(), inbounds(), LIQUID, item::made_of(), MAX_ITEM_IN_SQUARE, null_item_reference(), item::on_drop(), wrapped_vehicle::pos, route(), item_stack::size(), support_dirty(), item::typeId(), and item::volume().

Referenced by Character::absorb_hit(), computer_session::action_conveyor(), computer_session::action_data_anal(), computer_session::action_sample(), Character::activate_bionic(), add_corpse(), add_item_or_charges(), MapgenRemovePartHandler::add_item_or_charges(), jmapgen_liquid_item::apply(), butchery_drops_harvest(), butchery_quarter(), defense_game::caravan(), game::catch_a_monster(), activity_handlers::chop_logs_finish(), doors::close_door(), talk_function::companion_return(), complete_construction(), cycle_action(), iexamine::deployed_furniture(), game::disable_robot(), basecamp::distribute_food(), draw_lab(), Character::drop_invalid_inventory(), drop_items(), npc::drop_items(), drop_on_map(), drop_or_embed_projectile(), talk_function::drop_stolen_item(), talk_function::drop_weapon(), iexamine::elevator(), explosion_handler::emp_blast(), farm_action(), fetch_activity(), talk_function::field_plant(), activity_handlers::fill_liquid_do_turn(), iexamine::fireplace(), game::forced_door_closing(), fromPumpFuel(), iexamine::fvat_full(), iexamine::gaspump(), handle_harvest(), pickup::handle_spillable_contents(), iexamine::harvest_plant(), Character::i_add_or_drop(), map_stack::insert(), make_mon_corpse(), make_rubble(), mill_activate(), move_item(), MapExtras::mx_grave(), MapExtras::mx_mayhem(), MapExtras::mx_minefield(), iexamine::nanofab(), om_set_hide_site(), liquid_handler::perform_liquid_transfer(), iexamine::pit_covered(), Character::place_corpse(), basecamp::place_results(), activity_handlers::plant_seed_finish(), talk_function::player_weapon_drop(), iexamine::portable_structure(), process_fields_in_submap(), put_into_vehicle(), iexamine::quern_examine(), rcdrive(), rod_fish(), scatter_chunks(), set_item_map(), activity_handlers::shear_finish(), smash_items(), smoker_activate(), iexamine::smoker_options(), spawn_an_item(), spawn_artifact(), spawn_items(), spawn_natural_artifact(), item_contents::spill_contents(), mdeath::splatter(), stash_on_pet(), iexamine::toPumpFuel(), iexamine::trap(), iexamine::tree_maple(), iexamine::tree_maple_tapped(), unroll_digging(), and unpack_actor::use().

◆ add_light_from_items()

void map::add_light_from_items ( const tripoint p,
item_stack::iterator  begin,
item_stack::iterator  end 
)
private

Definition at line 63 of file lightmap.cpp.

65{
66 for( auto itm_it = begin; itm_it != end; ++itm_it ) {
67 float ilum = 0.0f; // brightness
68 units::angle iwidth = 0_degrees; // 0-360 degrees. 0 is a circular light_source
69 units::angle idir = 0_degrees; // otherwise, it's a light_arc pointed in this direction
70 if( itm_it->getlight( ilum, iwidth, idir ) ) {
71 if( iwidth > 0_degrees ) {
72 apply_light_arc( p, idir, ilum, iwidth );
73 } else {
74 add_light_source( p, ilum );
75 }
76 }
77 }
78}
void apply_light_arc(const tripoint &p, units::angle, float luminance, units::angle wideangle=30_degrees)
Definition: lightmap.cpp:1551
void add_light_source(const tripoint &p, float luminance)
Definition: lightmap.cpp:584

References add_light_source(), and apply_light_arc().

Referenced by generate_lightmap().

◆ add_light_source()

void map::add_light_source ( const tripoint p,
float  luminance 
)
private

Definition at line 584 of file lightmap.cpp.

585{
586 auto &light_source_buffer = get_cache( p.z ).light_source_buffer;
587 light_source_buffer[p.x][p.y] = std::max( luminance, light_source_buffer[p.x][p.y] );
588}
float light_source_buffer[MAPSIZE_X][MAPSIZE_Y]
Definition: map.h:318

References get_cache(), level_cache::light_source_buffer, tripoint::x, tripoint::y, and tripoint::z.

Referenced by add_light_from_items(), and generate_lightmap().

◆ add_roofs()

void map::add_roofs ( const tripoint grid)
protected

Hacks in missing roofs.

Should be removed when 3D mapgen is done.

Definition at line 7460 of file map.cpp.

7461{
7462 if( !zlevels ) {
7463 // No roofs required!
7464 // Why not? Because submaps below and above don't exist yet
7465 return;
7466 }
7467
7468 submap *const sub_here = get_submap_at_grid( grid );
7469 if( sub_here == nullptr ) {
7470 debugmsg( "Tried to add roofs/floors on null submap on %d,%d,%d",
7471 grid.x, grid.y, grid.z );
7472 return;
7473 }
7474
7475 bool check_roof = grid.z > -OVERMAP_DEPTH;
7476
7477 submap *const sub_below = check_roof ? get_submap_at_grid( grid + tripoint_below ) : nullptr;
7478
7479 if( check_roof && sub_below == nullptr ) {
7480 debugmsg( "Tried to add roofs to sm at %d,%d,%d, but sm below doesn't exist",
7481 grid.x, grid.y, grid.z );
7482 return;
7483 }
7484
7485 for( int x = 0; x < SEEX; x++ ) {
7486 for( int y = 0; y < SEEY; y++ ) {
7487 const ter_id ter_here = sub_here->get_ter( { x, y } );
7488 if( ter_here != t_open_air ) {
7489 continue;
7490 }
7491
7492 if( !check_roof ) {
7493 // Make sure we don't have open air at lowest z-level
7494 sub_here->set_ter( { x, y }, t_rock_floor );
7495 continue;
7496 }
7497
7498 const ter_t &ter_below = sub_below->get_ter( { x, y } ).obj();
7499 if( ter_below.roof ) {
7500 // TODO: Make roof variable a ter_id to speed this up
7501 sub_here->set_ter( { x, y }, ter_below.roof.id() );
7502 }
7503 }
7504 }
7505}
int_id< T > id() const
Translate the string based it to the matching integer based id.
Definition: ammo_effect.cpp:54
void set_ter(const point &p, ter_id terr)
Definition: submap.h:103
ter_id t_open_air
Definition: mapdata.cpp:727
ter_id t_rock_floor
Definition: mapdata.cpp:627
static constexpr tripoint tripoint_below
Definition: point.h:295
ter_str_id roof
Definition: mapdata.h:467

References debugmsg, get_submap_at_grid(), submap::get_ter(), grid, string_id< T >::id(), OVERMAP_DEPTH, ter_t::roof, SEEX, SEEY, submap::set_ter(), t_open_air, t_rock_floor, tripoint_below, and zlevels.

Referenced by loadn(), and shift().

◆ add_spawn()

void map::add_spawn ( const mtype_id type,
int  count,
const tripoint p,
bool  friendly = false,
int  faction_id = -1,
int  mission_id = -1,
const std::string &  name = "NONE" 
) const

Definition at line 5582 of file mapgen.cpp.

5584{
5585 if( p.x < 0 || p.x >= SEEX * my_MAPSIZE || p.y < 0 || p.y >= SEEY * my_MAPSIZE ) {
5586 debugmsg( "Bad add_spawn(%s, %d, %d, %d)", type.c_str(), count, p.x, p.y );
5587 return;
5588 }
5589 point offset;
5590 submap *place_on_submap = get_submap_at( p, offset );
5591
5592 if( !place_on_submap ) {
5593 debugmsg( "centadodecamonant doesn't exist in grid; within add_spawn(%s, %d, %d, %d, %d)",
5594 type.c_str(), count, p.x, p.y, p.z );
5595 return;
5596 }
5598 return;
5599 }
5600 spawn_point tmp( type, count, offset, faction_id, mission_id, friendly, name );
5601 place_on_submap->spawns.push_back( tmp );
5602}
static bool monster_is_blacklisted(const mtype_id &m)
Definition: mongroup.cpp:280
std::vector< spawn_point > spawns
Definition: submap.h:241
@ type
Definition: enums.h:75
constexpr size_t count()
Definition: fmtlib_core.h:1073

References detail::count(), debugmsg, friendly, get_submap_at(), MonsterGroupManager::monster_is_blacklisted(), my_MAPSIZE, name(), SEEX, SEEY, submap::spawns, type, tripoint::x, tripoint::y, and tripoint::z.

Referenced by jmapgen_monster::apply(), generate(), mission_start::kill_horde_master(), mapgen_ants_generic(), mapgen_ants_larvae(), mapgen_ants_queen(), mapgen_hive(), mapgen_road(), MapExtras::mx_collegekids(), MapExtras::mx_drugdeal(), MapExtras::mx_helicopter(), MapExtras::mx_house_spider(), MapExtras::mx_house_wasp(), MapExtras::mx_jabberwock(), MapExtras::mx_marloss_pilgrimage(), MapExtras::mx_military(), MapExtras::mx_roadblock(), MapExtras::mx_science(), MapExtras::mx_shia(), MapExtras::mx_spider(), mission_start::place_dog(), place_spawns(), mission_start::place_zombie_mom(), process_fields_in_submap(), and rotten_item_spawn().

◆ add_splash()

void map::add_splash ( const field_type_id type,
const tripoint center,
int  radius,
int  intensity 
)

Definition at line 5528 of file map.cpp.

5530{
5531 if( !type.id() ) {
5532 return;
5533 }
5534 // TODO: use Bresenham here and take obstacles into account
5535 for( const tripoint &pnt : points_in_radius( center, radius ) ) {
5536 if( trig_dist( pnt, center ) <= radius && !one_in( intensity ) ) {
5537 add_splatter( type, pnt );
5538 }
5539 }
5540}
tripoint_range< tripoint > points_in_radius(const tripoint &center, size_t radius, size_t radiusz=0) const
Definition: map.cpp:8605
void add_splatter(const field_type_id &type, const tripoint &where, int intensity=1)
Definition: map.cpp:5479
int trig_dist(const coords::coord_point< Point, Origin, Scale > &loc1, const coords::coord_point< Point, Origin, Scale > &loc2)
Definition: coordinates.h:512

References add_splatter(), center, one_in(), points_in_radius(), trig_dist(), and type.

Referenced by smash_items().

◆ add_splatter()

void map::add_splatter ( const field_type_id type,
const tripoint where,
int  intensity = 1 
)

Definition at line 5479 of file map.cpp.

5480{
5481 if( !type.id() || intensity <= 0 ) {
5482 return;
5483 }
5484 if( type.obj().is_splattering ) {
5485 if( const optional_vpart_position vp = veh_at( where ) ) {
5486 vehicle *const veh = &vp->vehicle();
5487 // Might be -1 if all the vehicle's parts at where are marked for removal
5488 const int part = veh->part_displayed_at( vp->mount() );
5489 if( part != -1 ) {
5490 veh->part( part ).blood += 200 * std::min( intensity, 3 ) / 3;
5491 return;
5492 }
5493 }
5494 }
5495 mod_field_intensity( where, type, intensity );
5496}
optional_vpart_position veh_at(const tripoint &p) const
Checks if tile is occupied by vehicle and by which part.
Definition: map.cpp:1009
int mod_field_intensity(const tripoint &p, const field_type_id &type, int offset)
Increment/decrement intensity of field entry at point, creating if not present, removing if intensity...
Definition: map.cpp:5322
Simple wrapper to forward functions that may return a cata::optional to vpart_position.
A vehicle as a whole with all its components.
Definition: vehicle.h:675
vehicle(const vproto_id &type_id, int init_veh_fuel=-1, int init_veh_status=-1)
Definition: vehicle.cpp:251
vehicle_part & part(int part_num)
Definition: vehicle.cpp:7080
int part_displayed_at(const point &dp) const
Returns which part (as an index into the parts list) is the one that will be displayed for the given ...
Definition: vehicle.cpp:2970
int blood
how much blood covers part (in turns).
Definition: vehicle.h:398

References vehicle_part::blood, mod_field_intensity(), vehicle::part(), vehicle::part_displayed_at(), type, veh_at(), and vehicle::vehicle().

Referenced by add_splash(), add_splatter_trail(), Creature::bleed(), activity_handlers::butcher_finish(), scatter_chunks(), and mdeath::splatter().

◆ add_splatter_trail()

void map::add_splatter_trail ( const field_type_id type,
const tripoint from,
const tripoint to 
)

Definition at line 5498 of file map.cpp.

5500{
5501 if( !type.id() ) {
5502 return;
5503 }
5504 auto trail = line_to( from, to );
5505 int remainder = trail.size();
5506 tripoint last_point = from;
5507 for( tripoint &elem : trail ) {
5508 add_splatter( type, elem );
5509 remainder--;
5510 if( obstructed_by_vehicle_rotation( last_point, elem ) ) {
5511 if( one_in( 2 ) ) {
5512 elem.x = last_point.x;
5513 add_splatter( type, elem, remainder );
5514 } else {
5515 elem.y = last_point.y;
5516 add_splatter( type, elem, remainder );
5517 }
5518 return;
5519 }
5520 if( impassable( elem ) ) { // Blood splatters stop at walls.
5521 add_splatter( type, elem, remainder );
5522 return;
5523 }
5524 last_point = elem;
5525 }
5526}
bool obstructed_by_vehicle_rotation(const tripoint &from, const tripoint &to) const
Checks if a rotated vehicle is blocking diagonal movement, tripoints must be adjacent.
Definition: map.cpp:6482
bool impassable(const tripoint &p) const
Definition: map.cpp:1795
std::vector< coords::coord_point< Point, Origin, Scale > > line_to(const coords::coord_point< Point, Origin, Scale > &loc1, const coords::coord_point< Point, Origin, Scale > &loc2)
Definition: coordinates.h:548

References add_splatter(), impassable(), line_to(), obstructed_by_vehicle_rotation(), one_in(), type, tripoint::x, and tripoint::y.

Referenced by activity_handlers::butcher_finish(), MapExtras::mx_casings(), MapExtras::mx_mayhem(), MapExtras::mx_minefield(), projectile_attack(), and activity_handlers::pulp_do_turn().

◆ add_vehicle() [1/4]

vehicle * map::add_vehicle ( const vgroup_id type,
const point p,
units::angle  dir,
int  init_veh_fuel = -1,
int  init_veh_status = -1,
bool  merge_wrecks = true 
)

Definition at line 5610 of file mapgen.cpp.

5612{
5613 return add_vehicle( type.obj().pick(), p, dir, veh_fuel, veh_status, merge_wrecks );
5614}
vehicle * add_vehicle(const vgroup_id &type, const tripoint &p, units::angle dir, int init_veh_fuel=-1, int init_veh_status=-1, bool merge_wrecks=true)
Definition: mapgen.cpp:5604

References add_vehicle(), and type.

◆ add_vehicle() [2/4]

◆ add_vehicle() [3/4]

vehicle * map::add_vehicle ( const vproto_id type,
const point p,
units::angle  dir,
int  init_veh_fuel = -1,
int  init_veh_status = -1,
bool  merge_wrecks = true 
)

Definition at line 5616 of file mapgen.cpp.

5618{
5619 return add_vehicle( type, tripoint( p, abs_sub.z ), dir, veh_fuel, veh_status, merge_wrecks );
5620}

References abs_sub, add_vehicle(), type, and tripoint::z.

◆ add_vehicle() [4/4]

vehicle * map::add_vehicle ( const vproto_id type,
const tripoint p,
units::angle  dir,
int  init_veh_fuel = -1,
int  init_veh_status = -1,
bool  merge_wrecks = true 
)

Definition at line 5622 of file mapgen.cpp.

5624{
5625 if( !type.is_valid() ) {
5626 debugmsg( "Nonexistent vehicle type: \"%s\"", type.c_str() );
5627 return nullptr;
5628 }
5629 if( !inbounds( p ) ) {
5630 dbg( DL::Warn ) << string_format( "Out of bounds add_vehicle t=%s d=%d p=%s",
5631 type, to_degrees( dir ), p.to_string() );
5632 return nullptr;
5633 }
5634
5635 // debugmsg("n=%d x=%d y=%d MAPSIZE=%d ^2=%d", nonant, x, y, MAPSIZE, MAPSIZE*MAPSIZE);
5636 auto veh = std::make_unique<vehicle>( type, veh_fuel, veh_status );
5637 tripoint p_ms = p;
5638 veh->sm_pos = ms_to_sm_remain( p_ms );
5639 veh->pos = p_ms.xy();
5640 veh->place_spawn_items();
5641 // for backwards compatibility, we always spawn with a pivot point of (0,0) so
5642 // that the mount at (0,0) is located at the spawn position.
5643 veh->set_facing_and_pivot( dir, point_zero, false );
5644 //debugmsg("adding veh: %d, sm: %d,%d,%d, pos: %d, %d", veh, veh->smx, veh->smy, veh->smz, veh->posx, veh->posy);
5645 std::unique_ptr<vehicle> placed_vehicle_up =
5646 add_vehicle_to_map( std::move( veh ), merge_wrecks );
5647 vehicle *placed_vehicle = placed_vehicle_up.get();
5648
5649 if( placed_vehicle != nullptr ) {
5650 submap *place_on_submap = get_submap_at_grid( placed_vehicle->sm_pos );
5651 place_on_submap->vehicles.push_back( std::move( placed_vehicle_up ) );
5652 place_on_submap->is_uniform = false;
5654
5655 auto &ch = get_cache( placed_vehicle->sm_pos.z );
5656 ch.vehicle_list.insert( placed_vehicle );
5657 add_vehicle_to_cache( placed_vehicle );
5658
5659 //debugmsg ("grid[%d]->vehicles.size=%d veh.parts.size=%d", nonant, grid[nonant]->vehicles.size(),veh.parts.size());
5660 }
5661 return placed_vehicle;
5662}
std::unique_ptr< vehicle > add_vehicle_to_map(std::unique_ptr< vehicle > veh, bool merge_wrecks)
Takes a vehicle already created with new and attempts to place it on the map, checking for collisions...
Definition: mapgen.cpp:5673
void add_vehicle_to_cache(vehicle *)
Definition: map.cpp:271
std::vector< std::unique_ptr< vehicle > > vehicles
Vehicles on this submap (their (0,0) point is on this submap).
Definition: submap.h:247
tripoint sm_pos
Submap coordinates of the currently loaded submap (see game::m) that contains this vehicle.
Definition: vehicle.h:1901
point ms_to_sm_remain(int &x, int &y)
@ Warn
Warning (default: enabled).
#define dbg(x)
Definition: mapgen.cpp:98
bool move(avatar &you, map &m, const tripoint &d)
constexpr double to_degrees(const units::angle v)
Definition: units_angle.h:36
static constexpr point point_zero
Definition: point.h:274
std::string string_format(std::string format, Args &&...args)
Simple wrapper over string_formatter::parse.
constexpr point xy() const
Definition: point.h:220
std::string to_string() const
Definition: point.cpp:16

References add_vehicle_to_cache(), add_vehicle_to_map(), dbg, debugmsg, get_cache(), get_submap_at_grid(), inbounds(), invalidate_max_populated_zlev(), submap::is_uniform, avatar_action::move(), ms_to_sm_remain(), point_zero, vehicle::sm_pos, string_format(), units::to_degrees(), tripoint::to_string(), type, submap::vehicles, Warn, tripoint::xy(), and tripoint::z.

◆ add_vehicle_to_cache()

void map::add_vehicle_to_cache ( vehicle veh)

Definition at line 271 of file map.cpp.

272{
273 if( veh == nullptr ) {
274 debugmsg( "Tried to add null vehicle to cache" );
275 return;
276 }
277
278 // Get parts
279 for( const vpart_reference &vpr : veh->get_all_parts() ) {
280 if( vpr.part().removed ) {
281 continue;
282 }
283 const tripoint p = veh->global_part_pos3( vpr.part() );
284 level_cache &ch = get_cache( p.z );
285 ch.veh_in_active_range = true;
286 ch.veh_cached_parts[p] = std::make_pair( veh, static_cast<int>( vpr.part_index() ) );
287 if( inbounds( p ) ) {
288 ch.veh_exists_at[p.x][p.y] = true;
289 }
290 }
291
293}
bool last_full_vehicle_list_dirty
Definition: map.h:2024
vehicle_part_range get_all_parts() const
Yields a range containing all parts (including broken ones) that can be iterated over.
Definition: vehicle.cpp:7070
tripoint global_part_pos3(const int &index) const
Get the coordinates of the studied part of the vehicle.
Definition: vehicle.cpp:3286
This is a wrapper over a vehicle pointer and a reference to a part of it.
bool veh_in_active_range
Definition: map.h:359
bool veh_exists_at[MAPSIZE_X][MAPSIZE_Y]
Definition: map.h:360
std::map< tripoint, std::pair< vehicle *, int > > veh_cached_parts
Definition: map.h:361

References debugmsg, vehicle::get_all_parts(), get_cache(), vehicle::global_part_pos3(), inbounds(), last_full_vehicle_list_dirty, level_cache::veh_cached_parts, level_cache::veh_exists_at, level_cache::veh_in_active_range, tripoint::x, tripoint::y, and tripoint::z.

Referenced by add_vehicle(), veh_interact::complete_vehicle(), displace_vehicle(), construct::done_vehicle(), loadn(), vehicle::part_removal_cleanup(), and reset_vehicle_cache().

◆ add_vehicle_to_map()

std::unique_ptr< vehicle > map::add_vehicle_to_map ( std::unique_ptr< vehicle veh,
bool  merge_wrecks 
)
private

Takes a vehicle already created with new and attempts to place it on the map, checking for collisions.

If the vehicle can't be placed, returns NULL, otherwise returns a pointer to the placed vehicle, which may not necessarily be the one passed in (if wreckage is created by fusing cars).

Parameters
vehThe vehicle to place on the map.
merge_wrecksWhether crashed vehicles become part of each other
Returns
The vehicle that was finally placed.

Definition at line 5673 of file mapgen.cpp.

5675{
5676 //We only want to check once per square, so loop over all structural parts
5677 std::vector<int> frame_indices = veh->all_parts_at_location( "structure" );
5678
5679 //Check for boat type vehicles that should be placeable in deep water
5680 const bool can_float = size( veh->get_avail_parts( "FLOATS" ) ) > 2;
5681
5682 //When hitting a wall, only smash the vehicle once (but walls many times)
5683 bool needs_smashing = false;
5684
5685 veh->attach();
5686 veh->refresh_position();
5687
5688 for( std::vector<int>::const_iterator part = frame_indices.begin();
5689 part != frame_indices.end(); part++ ) {
5690 const auto p = veh->global_part_pos3( *part );
5691
5692 //Don't spawn anything in water
5693 if( has_flag_ter( TFLAG_DEEP_WATER, p ) && !can_float ) {
5694 return nullptr;
5695 }
5696
5697 // Don't spawn shopping carts on top of another vehicle or other obstacle.
5698 if( veh->type == vproto_id( "shopping_cart" ) ) {
5699 if( veh_at( p ) || impassable( p ) ) {
5700 return nullptr;
5701 }
5702 }
5703
5704 //For other vehicles, simulate collisions with (non-shopping cart) stuff
5705 vehicle *const other_veh = veh_pointer_or_null( veh_at( p ) );
5706 if( other_veh != nullptr && other_veh->type != vproto_id( "shopping_cart" ) ) {
5707 if( !merge_wrecks ) {
5708 return nullptr;
5709 }
5710
5711 // Hard wreck-merging limit: 200 tiles
5712 // Merging is slow for big vehicles which lags the mapgen
5713 if( frame_indices.size() + other_veh->all_parts_at_location( "structure" ).size() > 200 ) {
5714 return nullptr;
5715 }
5716
5717 /* There's a vehicle here, so let's fuse them together into wreckage and
5718 * smash them up. It'll look like a nasty collision has occurred.
5719 * Trying to do a local->global->local conversion would be a major
5720 * headache, so instead, let's make another vehicle whose (0, 0) point
5721 * is the (0, 0) of the existing vehicle, convert the coordinates of both
5722 * vehicles into global coordinates, find the distance between them and
5723 * p and then install them that way.
5724 * Create a vehicle with type "null" so it starts out empty. */
5725 auto wreckage = std::make_unique<vehicle>();
5726 wreckage->pos = other_veh->pos;
5727 wreckage->sm_pos = other_veh->sm_pos;
5728
5729 //Where are we on the global scale?
5730 const tripoint global_pos = wreckage->global_pos3();
5731
5732 for( const vpart_reference &vpr : veh->get_all_parts() ) {
5733 const tripoint part_pos = veh->global_part_pos3( vpr.part() ) - global_pos;
5734 // TODO: change mount points to be tripoint
5735 wreckage->install_part( part_pos.xy(), vpr.part() );
5736 }
5737
5738 for( const vpart_reference &vpr : other_veh->get_all_parts() ) {
5739 const tripoint part_pos = other_veh->global_part_pos3( vpr.part() ) - global_pos;
5740 wreckage->install_part( part_pos.xy(), vpr.part() );
5741
5742 }
5743
5744 wreckage->name = _( "Wreckage" );
5745
5746 // Now get rid of the old vehicles
5747 std::unique_ptr<vehicle> old_veh = detach_vehicle( other_veh );
5748 // Failure has happened here when caches are corrupted due to bugs.
5749 // Add an assertion to avoid null-pointer dereference later.
5750 assert( old_veh );
5751
5752 // Try again with the wreckage
5753 std::unique_ptr<vehicle> new_veh = add_vehicle_to_map( std::move( wreckage ), true );
5754 if( new_veh != nullptr ) {
5755 new_veh->smash( *this );
5756 return new_veh;
5757 }
5758
5759 // If adding the wreck failed, we want to restore the vehicle we tried to merge with
5760 add_vehicle_to_map( std::move( old_veh ), false );
5761 return nullptr;
5762
5763 } else if( impassable( p ) ) {
5764 if( !merge_wrecks ) {
5765 return nullptr;
5766 }
5767
5768 // There's a wall or other obstacle here; destroy it
5769 destroy( p, true );
5770
5771 // Some weird terrain, don't place the vehicle
5772 if( impassable( p ) ) {
5773 return nullptr;
5774 }
5775
5776 needs_smashing = true;
5777 }
5778 }
5779
5780 if( needs_smashing ) {
5781 veh->smash( *this );
5782 }
5783
5784 return veh;
5785}
void destroy(const tripoint &p, bool silent=false)
Keeps bashing a square until it can't be bashed anymore.
Definition: map.cpp:3627
std::unique_ptr< vehicle > detach_vehicle(vehicle *veh)
Definition: map.cpp:354
bool has_flag_ter(const std::string &flag, const tripoint &p) const
Definition: map.cpp:2312
point pos
Position of the vehicle inside the submap that contains the vehicle.
Definition: vehicle.h:1916
vproto_id type
Type of the vehicle as it was spawned.
Definition: vehicle.h:1855
std::vector< int > all_parts_at_location(const std::string &location) const
Returns all parts in the vehicle that exist in the given location slot.
Definition: vehicle.cpp:2781
@ TFLAG_DEEP_WATER
Definition: mapdata.h:301
const size_t size
Definition: om_direction.h:27
#define _(msg)
Definition: translations.h:116
vehicle * veh_pointer_or_null(const optional_vpart_position &p)

References _, add_vehicle_to_map(), vehicle::all_parts_at_location(), destroy(), detach_vehicle(), vehicle::get_all_parts(), vehicle::global_part_pos3(), has_flag_ter(), impassable(), avatar_action::move(), vehicle::pos, om_direction::size, vehicle::sm_pos, TFLAG_DEEP_WATER, vehicle::type, veh_at(), veh_pointer_or_null(), and tripoint::xy().

Referenced by add_vehicle(), and add_vehicle_to_map().

◆ adjust_radiation() [1/2]

void map::adjust_radiation ( const point p,
const int  delta 
)
inline

Definition at line 1223 of file map.h.

1223 {
1224 adjust_radiation( tripoint( p, abs_sub.z ), delta );
1225 }
void adjust_radiation(const tripoint &p, int delta)
Increment the radiation in the given tile by the given delta (decrement it if delta is negative)
Definition: map.cpp:4047

References abs_sub, adjust_radiation(), and tripoint::z.

◆ adjust_radiation() [2/2]

void map::adjust_radiation ( const tripoint p,
int  delta 
)

Increment the radiation in the given tile by the given delta (decrement it if delta is negative)

Definition at line 4047 of file map.cpp.

4048{
4049 if( !inbounds( p ) ) {
4050 return;
4051 }
4052
4053 point l;
4054 submap *const current_submap = get_submap_at( p, l );
4055
4056 int current_radiation = current_submap->get_radiation( l );
4057 current_submap->set_radiation( l, current_radiation + delta );
4058}
void set_radiation(const point &p, const int radiation)
Definition: submap.h:116
int get_radiation(const point &p) const
Definition: submap.h:112

References submap::get_radiation(), get_submap_at(), inbounds(), and submap::set_radiation().

Referenced by computer_session::action_irradiator(), adjust_radiation(), MapExtras::mx_crater(), MapExtras::mx_portal_in(), and process_fields_in_submap().

◆ ambient_light_at()

float map::ambient_light_at ( const tripoint p) const

Definition at line 617 of file lightmap.cpp.

618{
619 if( !inbounds( p ) ) {
620 return 0.0f;
621 }
622
623 return get_cache_ref( p.z ).lm[p.x][p.y].max();
624}
const level_cache & get_cache_ref(int zlev) const
Definition: map.h:2040
float max() const
Definition: shadowcasting.h:45
four_quadrants lm[MAPSIZE_X][MAPSIZE_Y]
Definition: map.h:314

References get_cache_ref(), inbounds(), level_cache::lm, four_quadrants::max(), tripoint::x, tripoint::y, and tripoint::z.

Referenced by apply_character_light(), game::print_terrain_info(), and Creature::sees().

◆ apparent_light_at()

lit_level map::apparent_light_at ( const tripoint p,
const visibility_variables cache 
) const

Determine the visible light level for a tile, based on light_at for the tile, vision distance, etc.

Parameters
pThe tile on this map to draw.
cacheCurrently cached visibility parameters

Definition at line 700 of file lightmap.cpp.

701{
702 const int dist = rl_dist( g->u.pos(), p );
703
704 // Clairvoyance overrides everything.
705 if( dist <= cache.u_clairvoyance ) {
706 return lit_level::BRIGHT;
707 }
708 const auto &map_cache = get_cache_ref( p.z );
709 const apparent_light_info a = apparent_light_helper( map_cache, p );
710
711 // Unimpaired range is an override to strictly limit vision range based on various conditions,
712 // but the player can still see light sources.
713 if( dist > g->u.unimpaired_range() ) {
714 if( !a.obstructed && map_cache.sm[p.x][p.y] > 0.0 ) {
716 } else {
717 return lit_level::DARK;
718 }
719 }
720 if( a.obstructed ) {
721 if( a.apparent_light > LIGHT_AMBIENT_LIT ) {
722 if( a.apparent_light > cache.g_light_level ) {
723 // This represents too hazy to see detail,
724 // but enough light getting through to illuminate.
726 } else {
727 // If it's not brighter than the surroundings, it just ends up shadowy.
728 return lit_level::LOW;
729 }
730 } else {
731 return lit_level::BLANK;
732 }
733 }
734 // Then we just search for the light level in descending order.
735 if( a.apparent_light > LIGHT_SOURCE_BRIGHT || map_cache.sm[p.x][p.y] > 0.0 ) {
736 return lit_level::BRIGHT;
737 }
738 if( a.apparent_light > LIGHT_AMBIENT_LIT ) {
739 return lit_level::LIT;
740 }
741 if( a.apparent_light >= cache.vision_threshold ) {
742 return lit_level::LOW;
743 } else {
744 return lit_level::BLANK;
745 }
746}
static apparent_light_info apparent_light_helper(const level_cache &map_cache, const tripoint &p)
Helper function for light claculation; exposed here for map editor.
Definition: lightmap.cpp:638
int rl_dist(const coords::coord_point< Point, Origin, Scale > &loc1, const coords::coord_point< Point, Origin, Scale > &loc2)
Definition: coordinates.h:519
static constexpr float LIGHT_SOURCE_BRIGHT
Definition: lightmap.h:9
static constexpr float LIGHT_AMBIENT_LIT
Definition: lightmap.h:18
constexpr double a
Definition: magic.cpp:1030
float vision_threshold
Definition: map.h:128
int u_clairvoyance
Definition: map.h:127

References a, apparent_light_helper(), BLANK, BRIGHT, BRIGHT_ONLY, DARK, g, visibility_variables::g_light_level, get_cache_ref(), LIGHT_AMBIENT_LIT, LIGHT_SOURCE_BRIGHT, LIT, LOW, rl_dist(), visibility_variables::u_clairvoyance, visibility_variables::vision_threshold, tripoint::x, tripoint::y, and tripoint::z.

Referenced by game::draw_look_around_cursor(), game::print_all_tile_info(), editmap::update_view_with_help(), and update_visibility_cache().

◆ apparent_light_helper()

map::apparent_light_info map::apparent_light_helper ( const level_cache map_cache,
const tripoint p 
)
static

Helper function for light claculation; exposed here for map editor.

Definition at line 638 of file lightmap.cpp.

640{
641 const float vis = std::max( map_cache.seen_cache[p.x][p.y], map_cache.camera_cache[p.x][p.y] );
642 const bool obstructed = vis <= LIGHT_TRANSPARENCY_SOLID + 0.1;
643
644 auto is_opaque = [&map_cache]( const point & p ) {
645 return map_cache.transparency_cache[p.x][p.y] <= LIGHT_TRANSPARENCY_SOLID &&
647 };
648
649 const bool p_opaque = is_opaque( p.xy() );
650 float apparent_light;
651
652 if( p_opaque && vis > 0 ) {
653 // This is the complicated case. We want to check which quadrants the
654 // player can see the tile from, and only count light values from those
655 // quadrants.
656 struct offset_and_quadrants {
657 point offset;
658 std::array<quadrant, 2> quadrants;
659 };
660 static constexpr std::array<offset_and_quadrants, 8> adjacent_offsets = {{
669 }
670 };
671
672 four_quadrants seen_from( 0 );
673 for( const offset_and_quadrants &oq : adjacent_offsets ) {
674 const point neighbour = p.xy() + oq.offset;
675
676 if( !lightmap_boundaries.contains( neighbour ) ) {
677 continue;
678 }
679 if( is_opaque( neighbour ) ) {
680 continue;
681 }
682 if( map_cache.seen_cache[neighbour.x][neighbour.y] == 0 &&
683 map_cache.camera_cache[neighbour.x][neighbour.y] == 0 ) {
684 continue;
685 }
686 // This is a non-opaque visible neighbour, so count visibility from the relevant
687 // quadrants
688 seen_from[oq.quadrants[0]] = vis;
689 seen_from[oq.quadrants[1]] = vis;
690 }
691 apparent_light = ( seen_from * map_cache.lm[p.x][p.y] ).max();
692 } else {
693 // This is the simple case, for a non-opaque tile light from all
694 // directions is equivalent
695 apparent_light = vis * map_cache.lm[p.x][p.y].max();
696 }
697 return { obstructed, apparent_light };
698}
const half_open_rectangle< point > lightmap_boundaries(lightmap_boundary_min, lightmap_boundary_max)
static constexpr float LIGHT_TRANSPARENCY_SOLID
Transparency 101: Transparency usually ranges between 0.038 (open air) and 0.38 (regular smoke).
Definition: lightmap.h:32
static constexpr point point_south_west
Definition: point.h:281
static constexpr point point_west
Definition: point.h:282
static constexpr point point_north_east
Definition: point.h:277
static constexpr point point_north_west
Definition: point.h:283
static constexpr point point_south_east
Definition: point.h:279
static constexpr point point_south
Definition: point.h:280
static constexpr point point_north
Definition: point.h:276
static constexpr point point_east
Definition: point.h:278
float seen_cache[MAPSIZE_X][MAPSIZE_Y]
Definition: map.h:348
float transparency_cache[MAPSIZE_X][MAPSIZE_Y]
Definition: map.h:332
float vision_transparency_cache[MAPSIZE_X][MAPSIZE_Y]
Definition: map.h:344
float camera_cache[MAPSIZE_X][MAPSIZE_Y]
Definition: map.h:352
int y
Definition: point.h:39
int x
Definition: point.h:38

References level_cache::camera_cache, LIGHT_TRANSPARENCY_SOLID, lightmap_boundaries, level_cache::lm, four_quadrants::max(), NE, NW, point_east, point_north, point_north_east, point_north_west, point_south, point_south_east, point_south_west, point_west, SE, level_cache::seen_cache, SW, level_cache::transparency_cache, level_cache::vision_transparency_cache, point::x, tripoint::x, tripoint::xy(), point::y, and tripoint::y.

Referenced by apparent_light_at(), pl_sees(), and editmap::update_view_with_help().

◆ apply_character_light()

void map::apply_character_light ( Character p)
protected

Definition at line 198 of file lightmap.cpp.

199{
200 if( p.has_effect( effect_onfire ) ) {
201 apply_light_source( p.pos(), 8 );
202 } else if( p.has_effect( effect_haslight ) ) {
203 apply_light_source( p.pos(), 4 );
204 }
205
206 const float held_luminance = p.active_light();
207 if( held_luminance > LIGHT_AMBIENT_LOW ) {
208 apply_light_source( p.pos(), held_luminance );
209 }
210
211 if( held_luminance >= 4 && held_luminance > ambient_light_at( p.pos() ) - 0.5f ) {
212 p.add_effect( effect_haslight, 1_turns );
213 }
214}
float active_light() const
Returns character luminosity based on the brightest active item they are carrying.
Definition: character.cpp:6377
void add_effect(const effect &eff, bool force=false, bool deferred=false)
Definition: creature.cpp:980
bool has_effect(const efftype_id &eff_id, body_part bp=num_bp) const
Check if creature has the matching effect.
Definition: creature.cpp:1179
void apply_light_source(const tripoint &p, float luminance)
Definition: lightmap.cpp:1430
float ambient_light_at(const tripoint &p) const
Definition: lightmap.cpp:617
static const efftype_id effect_haslight("haslight")
static const efftype_id effect_onfire("onfire")
static constexpr float LIGHT_AMBIENT_LOW
Definition: lightmap.h:14

References Character::active_light(), Creature::add_effect(), ambient_light_at(), apply_light_source(), effect_haslight, effect_onfire, Creature::has_effect(), LIGHT_AMBIENT_LOW, and Character::pos().

Referenced by generate_lightmap().

◆ apply_directional_light()

void map::apply_directional_light ( const tripoint p,
int  direction,
float  luminance 
)
private

Definition at line 1511 of file lightmap.cpp.

1512{
1513 const point p2( p.xy() );
1514
1515 auto &cache = get_cache( p.z );
1516 four_quadrants( &lm )[MAPSIZE_X][MAPSIZE_Y] = cache.lm;
1517 float ( &transparency_cache )[MAPSIZE_X][MAPSIZE_Y] = cache.transparency_cache;
1518 diagonal_blocks( &blocked_cache )[MAPSIZE_X][MAPSIZE_Y] = cache.vehicle_obscured_cache;
1519
1520 if( direction == 90 ) {
1521 castLight < 1, 0, 0, -1, float, four_quadrants, light_calc, light_check,
1523 lm, transparency_cache, blocked_cache, p2, 0, luminance );
1524 castLight < -1, 0, 0, -1, float, four_quadrants, light_calc, light_check,
1526 lm, transparency_cache, blocked_cache, p2, 0, luminance );
1527 } else if( direction == 0 ) {
1528 castLight < 0, -1, 1, 0, float, four_quadrants, light_calc, light_check,
1530 lm, transparency_cache, blocked_cache, p2, 0, luminance );
1531 castLight < 0, -1, -1, 0, float, four_quadrants, light_calc, light_check,
1533 lm, transparency_cache, blocked_cache, p2, 0, luminance );
1534 } else if( direction == 270 ) {
1535 castLight<1, 0, 0, 1, float, four_quadrants, light_calc, light_check,
1537 lm, transparency_cache, blocked_cache, p2, 0, luminance );
1538 castLight < -1, 0, 0, 1, float, four_quadrants, light_calc, light_check,
1540 lm, transparency_cache, blocked_cache, p2, 0, luminance );
1541 } else if( direction == 180 ) {
1542 castLight<0, 1, 1, 0, float, four_quadrants, light_calc, light_check,
1544 lm, transparency_cache, blocked_cache, p2, 0, luminance );
1545 castLight < 0, 1, -1, 0, float, four_quadrants, light_calc, light_check,
1547 lm, transparency_cache, blocked_cache, p2, 0, luminance );
1548 }
1549}
static constexpr int MAPSIZE_Y
static constexpr int MAPSIZE_X
void castLight(Out(&output_cache)[MAPSIZE_X][MAPSIZE_Y], const T(&input_array)[MAPSIZE_X][MAPSIZE_Y], const diagonal_blocks(&blocked_array)[MAPSIZE_X][MAPSIZE_Y], const point &offset, int offsetDistance, T numerator=VISIBILITY_FULL, int row=1, float start=1.0f, float end=0.0f, T cumulative_transparency=LIGHT_TRANSPARENCY_OPEN_AIR)
Definition: lightmap.cpp:1125
static bool light_check(const float &transparency, const float &intensity)
Definition: lightmap.cpp:1425
static float light_calc(const float &numerator, const float &transparency, const int &distance)
Definition: lightmap.cpp:1418
direction
Definition: line.h:39
void update_light_quadrants(four_quadrants &update, const float &new_value, quadrant q)
Definition: shadowcasting.h:97
float accumulate_transparency(const float &cumulative_transparency, const float &current_transparency, const int &distance)

References accumulate_transparency(), castLight(), get_cache(), light_calc(), light_check(), MAPSIZE_X, MAPSIZE_Y, update_light_quadrants(), tripoint::xy(), and tripoint::z.

Referenced by generate_lightmap().

◆ apply_faction_ownership()

void map::apply_faction_ownership ( const point p1,
const point p2,
const faction_id id 
)

Definition at line 5498 of file mapgen.cpp.

5499{
5500 for( const tripoint &p : points_in_rectangle( tripoint( p1, abs_sub.z ), tripoint( p2,
5501 abs_sub.z ) ) ) {
5502 auto items = i_at( p.xy() );
5503 for( item &elem : items ) {
5504 elem.set_owner( id );
5505 }
5506 vehicle *source_veh = veh_pointer_or_null( veh_at( p ) );
5507 if( source_veh ) {
5508 if( !source_veh->has_owner() ) {
5509 source_veh->set_owner( id );
5510 }
5511 }
5512 }
5513}
tripoint_range< tripoint > points_in_rectangle(const tripoint &from, const tripoint &to) const
Definition: map.cpp:8595
bool has_owner() const
Definition: vehicle.h:844
void set_owner(const faction_id &new_owner)
Definition: vehicle.h:831

References abs_sub, vehicle::has_owner(), i_at(), points_in_rectangle(), vehicle::set_owner(), veh_at(), veh_pointer_or_null(), and tripoint::z.

Referenced by jmapgen_faction::apply().

◆ apply_light_arc()

void map::apply_light_arc ( const tripoint p,
units::angle  angle,
float  luminance,
units::angle  wideangle = 30_degrees 
)
private

Definition at line 1551 of file lightmap.cpp.

1553{
1554 if( luminance <= LIGHT_SOURCE_LOCAL ) {
1555 return;
1556 }
1557
1558 bool lit[LIGHTMAP_CACHE_X][LIGHTMAP_CACHE_Y] {};
1559
1561
1562 // Normalize (should work with negative values too)
1563 const units::angle wangle = wideangle / 2.0;
1564
1565 units::angle nangle = fmod( angle, 360_degrees );
1566
1567 tripoint end;
1568 int range = LIGHT_RANGE( luminance );
1569 calc_ray_end( nangle, range, p, end );
1570 apply_light_ray( lit, p, end, luminance );
1571
1572 tripoint test;
1573 calc_ray_end( wangle + nangle, range, p, test );
1574
1575 const float wdist = hypot( end.x - test.x, end.y - test.y );
1576 if( wdist <= 0.5 ) {
1577 return;
1578 }
1579
1580 // attempt to determine beam intensity required to cover all squares
1581 const units::angle wstep = ( wangle / ( wdist * M_SQRT2 ) );
1582
1583 // NOLINTNEXTLINE(clang-analyzer-security.FloatLoopCounter)
1584 for( units::angle ao = wstep; ao <= wangle; ao += wstep ) {
1585 if( trigdist ) {
1586 double fdist = ( ao * M_PI_2 ) / wangle;
1587 end.x = static_cast<int>(
1588 p.x + ( static_cast<double>( range ) - fdist * 2.0 ) * cos( nangle + ao ) );
1589 end.y = static_cast<int>(
1590 p.y + ( static_cast<double>( range ) - fdist * 2.0 ) * sin( nangle + ao ) );
1591 apply_light_ray( lit, p, end, luminance );
1592
1593 end.x = static_cast<int>(
1594 p.x + ( static_cast<double>( range ) - fdist * 2.0 ) * cos( nangle - ao ) );
1595 end.y = static_cast<int>(
1596 p.y + ( static_cast<double>( range ) - fdist * 2.0 ) * sin( nangle - ao ) );
1597 apply_light_ray( lit, p, end, luminance );
1598 } else {
1599 calc_ray_end( nangle + ao, range, p, end );
1600 apply_light_ray( lit, p, end, luminance );
1601 calc_ray_end( nangle - ao, range, p, end );
1602 apply_light_ray( lit, p, end, luminance );
1603 }
1604 }
1605}
bool trigdist
Circular distances.
void apply_light_ray(bool lit[MAPSIZE_X][MAPSIZE_Y], const tripoint &s, const tripoint &e, float luminance)
Definition: lightmap.cpp:1607
static constexpr int LIGHTMAP_CACHE_Y
Definition: lightmap.cpp:48
static constexpr int LIGHTMAP_CACHE_X
Definition: lightmap.cpp:47
static constexpr float LIGHT_SOURCE_LOCAL
Definition: lightmap.h:8
#define LIGHT_RANGE(b)
Definition: lightmap.h:41
void calc_ray_end(units::angle angle, const int range, const tripoint &p, tripoint &out)
Definition: line.cpp:751
#define M_SQRT2
Definition: math_defines.h:29
#define M_PI_2
Definition: math_defines.h:25
quantity< double, angle_in_radians_tag > angle
Definition: units_angle.h:17
double sin(angle a)
Definition: units_angle.h:52
double cos(angle a)
Definition: units_angle.h:57
quantity< V, U > fmod(quantity< V, U > num, quantity< V, U > den)
Definition: units_def.h:142

References apply_light_ray(), apply_light_source(), calc_ray_end(), units::cos(), units::fmod(), LIGHT_RANGE, LIGHT_SOURCE_LOCAL, LIGHTMAP_CACHE_X, LIGHTMAP_CACHE_Y, M_PI_2, M_SQRT2, units::sin(), trigdist, tripoint::x, and tripoint::y.

Referenced by add_light_from_items(), and generate_lightmap().

◆ apply_light_ray()

void map::apply_light_ray ( bool  lit[MAPSIZE_X][MAPSIZE_Y],
const tripoint s,
const tripoint e,
float  luminance 
)
private

Definition at line 1607 of file lightmap.cpp.

1609{
1610 point a( std::abs( e.x - s.x ) * 2, std::abs( e.y - s.y ) * 2 );
1611 point d( ( s.x < e.x ) ? 1 : -1, ( s.y < e.y ) ? 1 : -1 );
1612 point p( s.xy() );
1613
1614 quadrant quad = quadrant_from_x_y( d.x, d.y );
1615
1616 // TODO: Invert that z comparison when it's sane
1617 if( s.z != e.z || ( s.x == e.x && s.y == e.y ) ) {
1618 return;
1619 }
1620
1621 auto &lm = get_cache( s.z ).lm;
1622 auto &transparency_cache = get_cache( s.z ).transparency_cache;
1623
1624 float distance = 1.0;
1625 float transparency = LIGHT_TRANSPARENCY_OPEN_AIR;
1626 const float scaling_factor = static_cast<float>( rl_dist( s, e ) ) /
1627 static_cast<float>( square_dist( s, e ) );
1628 // TODO: [lightmap] Pull out the common code here rather than duplication
1629 if( a.x > a.y ) {
1630 int t = a.y - ( a.x / 2 );
1631 do {
1632 if( t >= 0 ) {
1633 p.y += d.y;
1634 t -= a.x;
1635 }
1636
1637 p.x += d.x;
1638 t += a.y;
1639
1640 // TODO: clamp coordinates to map bounds before this method is called.
1641 if( lightmap_boundaries.contains( p ) ) {
1642 float current_transparency = transparency_cache[p.x][p.y];
1643 bool is_opaque = ( current_transparency == LIGHT_TRANSPARENCY_SOLID );
1644 if( !lit[p.x][p.y] ) {
1645 // Multiple rays will pass through the same squares so we need to record that
1646 lit[p.x][p.y] = true;
1647 float lm_val = luminance / ( fastexp( transparency * distance ) * distance );
1648 quadrant q = is_opaque ? quad : quadrant::default_;
1649 lm[p.x][p.y][q] = std::max( lm[p.x][p.y][q], lm_val );
1650 }
1651 if( is_opaque ) {
1652 break;
1653 }
1654 // Cumulative average of the transparency values encountered.
1655 transparency = ( ( distance - 1.0 ) * transparency + current_transparency ) / distance;
1656 } else {
1657 break;
1658 }
1659
1660 distance += scaling_factor;
1661 } while( !( p.x == e.x && p.y == e.y ) );
1662 } else {
1663 int t = a.x - ( a.y / 2 );
1664 do {
1665 if( t >= 0 ) {
1666 p.x += d.x;
1667 t -= a.y;
1668 }
1669
1670 p.y += d.y;
1671 t += a.x;
1672
1673 if( lightmap_boundaries.contains( p ) ) {
1674 float current_transparency = transparency_cache[p.x][p.y];
1675 bool is_opaque = ( current_transparency == LIGHT_TRANSPARENCY_SOLID );
1676 if( !lit[p.x][p.y] ) {
1677 // Multiple rays will pass through the same squares so we need to record that
1678 lit[p.x][p.y] = true;
1679 float lm_val = luminance / ( fastexp( transparency * distance ) * distance );
1680 quadrant q = is_opaque ? quad : quadrant::default_;
1681 lm[p.x][p.y][q] = std::max( lm[p.x][p.y][q], lm_val );
1682 }
1683 if( is_opaque ) {
1684 break;
1685 }
1686 // Cumulative average of the transparency values encountered.
1687 transparency = ( ( distance - 1.0 ) * transparency + current_transparency ) / distance;
1688 } else {
1689 break;
1690 }
1691
1692 distance += scaling_factor;
1693 } while( !( p.x == e.x && p.y == e.y ) );
1694 }
1695}
int square_dist(const coords::coord_point< Point, Origin, Scale > &loc1, const coords::coord_point< Point, Origin, Scale > &loc2)
Definition: coordinates.h:505
static constexpr quadrant quadrant_from_x_y(int x, int y)
Definition: lightmap.cpp:786
static float fastexp(float x)
Definition: lightmap.cpp:1402
static constexpr float LIGHT_TRANSPARENCY_OPEN_AIR
Definition: lightmap.h:36
quadrant
Definition: shadowcasting.h:22

References a, default_, fastexp(), get_cache(), LIGHT_TRANSPARENCY_OPEN_AIR, LIGHT_TRANSPARENCY_SOLID, lightmap_boundaries, level_cache::lm, quadrant_from_x_y(), rl_dist(), square_dist(), level_cache::transparency_cache, point::x, tripoint::x, tripoint::xy(), point::y, tripoint::y, and tripoint::z.

Referenced by apply_light_arc().

◆ apply_light_source()

void map::apply_light_source ( const tripoint p,
float  luminance 
)
private

Definition at line 1430 of file lightmap.cpp.

1431{
1432 auto &cache = get_cache( p.z );
1433 four_quadrants( &lm )[MAPSIZE_X][MAPSIZE_Y] = cache.lm;
1434 float ( &sm )[MAPSIZE_X][MAPSIZE_Y] = cache.sm;
1435 float ( &transparency_cache )[MAPSIZE_X][MAPSIZE_Y] = cache.transparency_cache;
1436 float ( &light_source_buffer )[MAPSIZE_X][MAPSIZE_Y] = cache.light_source_buffer;
1437 diagonal_blocks( &blocked_cache )[MAPSIZE_X][MAPSIZE_Y] = cache.vehicle_obscured_cache;
1438
1439 const point p2( p.xy() );
1440
1441 if( inbounds( p ) ) {
1442 const float min_light = std::max( static_cast<float>( lit_level::LOW ), luminance );
1443 lm[p2.x][p2.y] = elementwise_max( lm[p2.x][p2.y], min_light );
1444 sm[p2.x][p2.y] = std::max( sm[p2.x][p2.y], luminance );
1445 }
1446 if( luminance <= lit_level::LOW ) {
1447 return;
1448 } else if( luminance <= lit_level::BRIGHT_ONLY ) {
1449 luminance = 1.49f;
1450 }
1451
1452 /* If we're a 5 luminance fire , we skip casting rays into ey && sx if we have
1453 neighboring fires to the north and west that were applied via light_source_buffer
1454 If there's a 1 luminance candle east in buffer, we still cast rays into ex since it's smaller
1455 If there's a 100 luminance magnesium flare south added via apply_light_source instead od
1456 add_light_source, it's unbuffered so we'll still cast rays into sy.
1457
1458 ey
1459 nnnNnnn
1460 w e
1461 w 5 +e
1462 sx W 5*1+E ex
1463 w ++++e
1464 w+++++e
1465 sssSsss
1466 sy
1467 */
1468 const int peer_inbounds = LIGHTMAP_CACHE_X - 1;
1469 bool north = ( p2.y != 0 && light_source_buffer[p2.x][p2.y - 1] < luminance );
1470 bool south = ( p2.y != peer_inbounds && light_source_buffer[p2.x][p2.y + 1] < luminance );
1471 bool east = ( p2.x != peer_inbounds && light_source_buffer[p2.x + 1][p2.y] < luminance );
1472 bool west = ( p2.x != 0 && light_source_buffer[p2.x - 1][p2.y] < luminance );
1473
1474 if( north ) {
1475 castLight < 1, 0, 0, -1, float, four_quadrants, light_calc, light_check,
1477 lm, transparency_cache, blocked_cache, p2, 0, luminance );
1478 castLight < -1, 0, 0, -1, float, four_quadrants, light_calc, light_check,
1480 lm, transparency_cache, blocked_cache, p2, 0, luminance );
1481 }
1482
1483 if( east ) {
1484 castLight < 0, -1, 1, 0, float, four_quadrants, light_calc, light_check,
1486 lm, transparency_cache, blocked_cache, p2, 0, luminance );
1487 castLight < 0, -1, -1, 0, float, four_quadrants, light_calc, light_check,
1489 lm, transparency_cache, blocked_cache, p2, 0, luminance );
1490 }
1491
1492 if( south ) {
1493 castLight<1, 0, 0, 1, float, four_quadrants, light_calc, light_check,
1495 lm, transparency_cache, blocked_cache, p2, 0, luminance );
1496 castLight < -1, 0, 0, 1, float, four_quadrants, light_calc, light_check,
1498 lm, transparency_cache, blocked_cache, p2, 0, luminance );
1499 }
1500
1501 if( west ) {
1502 castLight<0, 1, 1, 0, float, four_quadrants, light_calc, light_check,
1504 lm, transparency_cache, blocked_cache, p2, 0, luminance );
1505 castLight < 0, 1, -1, 0, float, four_quadrants, light_calc, light_check,
1507 lm, transparency_cache, blocked_cache, p2, 0, luminance );
1508 }
1509}
constexpr scale sm
Definition: coordinates.h:31

References accumulate_transparency(), BRIGHT_ONLY, castLight(), get_cache(), inbounds(), light_calc(), light_check(), LIGHTMAP_CACHE_X, LOW, MAPSIZE_X, MAPSIZE_Y, coords::sm, update_light_quadrants(), point::x, tripoint::xy(), point::y, and tripoint::z.

Referenced by apply_character_light(), apply_light_arc(), and generate_lightmap().

◆ bash()

bash_results map::bash ( const tripoint p,
int  str,
bool  silent = false,
bool  destroy = false,
bool  bash_floor = false,
const vehicle bashing_vehicle = nullptr 
)

Returns a pair where first is whether anything was smashed and second is if it was destroyed.

Parameters
pWhere to bash
strHow hard to bash
silentDon't produce any sound
destroyDestroys some otherwise unbashable tiles
bash_floorAllow bashing the floor and the tile that supports it
bashing_vehicleVehicle that should NOT be bashed (because it is doing the bashing)

Definition at line 3516 of file map.cpp.

3519{
3520 bash_params bsh{
3521 str, silent, destroy, bash_floor, static_cast<float>( rng_float( 0, 1.0f ) ), false, true
3522 };
3524 if( !inbounds( p ) ) {
3525 return result;
3526 }
3527
3528 bool bashed_sealed = false;
3529 if( has_flag( "SEALED", p ) ) {
3530 result |= bash_ter_furn( p, bsh );
3531 bashed_sealed = true;
3532 }
3533
3534 result |= bash_field( p, bsh );
3535
3536 // Don't bash items inside terrain/furniture with SEALED flag
3537 if( !bashed_sealed ) {
3538 result |= bash_items( p, bsh );
3539 }
3540 // Don't bash the vehicle doing the bashing
3541 const vehicle *veh = veh_pointer_or_null( veh_at( p ) );
3542 if( veh != nullptr && veh != bashing_vehicle ) {
3543 result |= bash_vehicle( p, bsh );
3544 }
3545
3546 // If we still didn't bash anything solid (a vehicle) or a tile with SEALED flag, bash ter/furn
3547 if( !result.bashed_solid && !bashed_sealed ) {
3548 result |= bash_ter_furn( p, bsh );
3549 }
3550
3551 return result;
3552}
bash_results bash_field(const tripoint &p, const bash_params &params)
Definition: map.cpp:3606
bash_results bash_items(const tripoint &p, const bash_params &params)
Definition: map.cpp:3554
bash_results bash_vehicle(const tripoint &p, const bash_params &params)
Definition: map.cpp:3588
bash_results bash_ter_furn(const tripoint &p, const bash_params &params)
Definition: map.cpp:3392
double rng_float(double lo, double hi)
Definition: rng.cpp:28
@ silent
Definition: weather_type.h:56

References bash_field(), bash_items(), bash_ter_furn(), bash_vehicle(), destroy(), has_flag(), inbounds(), rng_float(), silent, veh_at(), and veh_pointer_or_null().

Referenced by Character::activate_bionic(), jmapgen_setmap::apply(), bash_furn_success(), bash_resistance(), bash_strength(), bash_ter_furn(), bash_ter_success(), batter(), destroy(), destroy_furn(), explosion_handler::do_blast(), drop_furniture(), drop_items(), game::fling_creature(), is_bashable(), game::knockback(), npc::move_to(), vehicle::part_collision(), player::reach_attack(), route(), scatter_chunks(), shoot(), explosion_handler::shrapnel(), mattack::shriek_stun(), smash(), and valid_move().

◆ bash_field()

bash_results map::bash_field ( const tripoint p,
const bash_params params 
)

Definition at line 3606 of file map.cpp.

3607{
3609 if( get_field( p, fd_web ) != nullptr ) {
3610 result.did_bash = true;
3611 result.bashed_solid = true; // To prevent bashing furniture/vehicles
3612 remove_field( p, fd_web );
3613 }
3614
3615 return result;
3616}
void remove_field(const tripoint &p, const field_type_id &field_to_remove)
Remove field entry at xy, ignored if the field entry is not present.
Definition: map.cpp:5453
field_type_id fd_web
Definition: field_type.cpp:340

References fd_web, get_field(), and remove_field().

Referenced by bash().

◆ bash_furn_success()

bash_results map::bash_furn_success ( const tripoint p,
const bash_params params 
)

Definition at line 3292 of file map.cpp.

3293{
3295 const auto &furnid = furn( p ).obj();
3296 const map_bash_info &bash = furnid.bash;
3297
3298
3299 if( has_flag_furn( "FUNGUS", p ) ) {
3300 fungal_effects( *g, *this ).create_spores( p );
3301 }
3302 if( has_flag_furn( "MIGO_NERVE", p ) ) {
3303 map_funcs::migo_nerve_cage_removal( *this, p, true );
3304 }
3305 std::string soundfxvariant = furnid.id.str();
3306 const bool tent = !bash.tent_centers.empty();
3307
3308 // Special code to collapse the tent if destroyed
3309 if( tent ) {
3310 // Get ids of possible centers
3311 std::set<furn_id> centers;
3312 for( const auto &cur_id : bash.tent_centers ) {
3313 if( cur_id.is_valid() ) {
3314 centers.insert( cur_id );
3315 }
3316 }
3317
3319
3320 // Find the center of the tent
3321 // First check if we're not currently bashing the center
3322 if( centers.count( furn( p ) ) > 0 ) {
3323 tentp.emplace( p, furn( p ) );
3324 } else {
3325 for( const tripoint &pt : points_in_radius( p, bash.collapse_radius ) ) {
3326 const furn_id &f_at = furn( pt );
3327 // Check if we found the center of the current tent
3328 if( centers.count( f_at ) > 0 ) {
3329 tentp.emplace( pt, f_at );
3330 break;
3331 }
3332 }
3333 }
3334 // Didn't find any tent center, wreck the current tile
3335 if( !tentp ) {
3337 furn_set( p, bash.furn_set );
3338 } else {
3339 // Take the tent down
3340 const int rad = tentp->second.obj().bash.collapse_radius;
3341 for( const tripoint &pt : points_in_radius( tentp->first, rad ) ) {
3342 const furn_id frn = furn( pt );
3343 if( frn == f_null ) {
3344 continue;
3345 }
3346
3347 const map_bash_info &recur_bash = frn.obj().bash;
3348 // Check if we share a center type and thus a "tent type"
3349 for( const auto &cur_id : recur_bash.tent_centers ) {
3350 if( centers.count( cur_id.id() ) > 0 ) {
3351 // Found same center, wreck current tile
3353 furn_set( pt, recur_bash.furn_set );
3354 break;
3355 }
3356 }
3357 }
3358 }
3359 soundfxvariant = "smash_cloth";
3360 } else {
3361 furn_set( p, bash.furn_set );
3362 for( item &it : i_at( p ) ) {
3363 it.on_drop( p, *this );
3364 }
3365 // HACK: Hack alert.
3366 // Signs have cosmetics associated with them on the submap since
3367 // furniture can't store dynamic data to disk. To prevent writing
3368 // mysteriously appearing for a sign later built here, remove the
3369 // writing from the submap.
3370 delete_signage( p );
3371 }
3372
3373 if( !tent ) {
3375 }
3376
3377 if( !bash.sound.empty() && !params.silent ) {
3378 static const std::string soundfxid = "smash_success";
3379 int sound_volume = get_sound_volume( bash );
3380 sounds::sound( p, sound_volume, sounds::sound_t::combat, bash.sound, false,
3381 soundfxid, soundfxvariant );
3382 }
3383
3384 if( bash.explosive > 0 ) {
3385 // TODO implement if the player triggered the explosive furniture
3386 explosion_handler::explosion( p, nullptr, bash.explosive, 0.8, false );
3387 }
3388
3389 return result;
3390}
T & emplace(Args &&... args)
Definition: optional.h:146
void create_spores(const tripoint &p, Creature *origin=nullptr)
Makes spores at p.
bool has_flag_furn(const std::string &flag, const tripoint &p) const
Definition: map.cpp:2317
bash_results bash(const tripoint &p, int str, bool silent=false, bool destroy=false, bool bash_floor=false, const vehicle *bashing_vehicle=nullptr)
Returns a pair where first is whether anything was smashed and second is if it was destroyed.
Definition: map.cpp:3516
std::vector< item * > spawn_items(const tripoint &p, const std::vector< item > &new_items)
Definition: map.cpp:4152
void furn_set(const tripoint &p, const furn_id &new_furniture, cata::poly_serialized< active_tile_data > new_active=nullptr)
Sets the furniture at given position.
Definition: map.cpp:1360
void delete_signage(const tripoint &p) const
Definition: map.cpp:4011
static int get_sound_volume(const map_bash_info &bash)
Definition: map.cpp:3154
furn_id f_null
Definition: mapdata.cpp:1095
void explosion(const tripoint &p, Creature *source, float power, float factor, bool fire, int legacy_casing_mass, float)
Legacy explosion function.
Definition: explosion.cpp:785
ItemList items_from(const item_group_id &group_id, const time_point &birthday)
Create items from the given group.
Definition: item_group.cpp:574
void migo_nerve_cage_removal(map &m, const tripoint &p, bool spawn_damaged)
void sound(const tripoint &p, int vol, sound_t category, const std::string &description, bool ambient=false, const std::string &id="", const std::string &variant="default")
Sound at (p) of intensity (vol)
Definition: sounds.cpp:177
bool silent
Definition: map.h:136
std::vector< furn_str_id > tent_centers
Definition: mapdata.h:100
item_group_id drop_group
Definition: mapdata.h:86
furn_str_id furn_set
Definition: mapdata.h:98
map_bash_info bash
Definition: mapdata.h:344

References bash(), map_data_common_t::bash, sounds::combat, fungal_effects::create_spores(), delete_signage(), map_bash_info::drop_group, cata::optional< T >::emplace(), explosion_handler::explosion(), f_null, furn(), furn_set(), map_bash_info::furn_set, g, get_sound_volume(), has_flag_furn(), i_at(), item_group::items_from(), map_funcs::migo_nerve_cage_removal(), int_id< T >::obj(), points_in_radius(), bash_params::silent, sounds::sound(), spawn_items(), map_bash_info::tent_centers, and calendar::turn.

Referenced by bash_ter_furn().

◆ bash_items()

bash_results map::bash_items ( const tripoint p,
const bash_params params 
)

Definition at line 3554 of file map.cpp.

3555{
3557 if( !has_items( p ) ) {
3558 return result;
3559 }
3560
3561 std::vector<item> smashed_contents;
3562 auto bashed_items = i_at( p );
3563 bool smashed_glass = false;
3564 for( auto bashed_item = bashed_items.begin(); bashed_item != bashed_items.end(); ) {
3565 // the check for active suppresses Molotovs smashing themselves with their own explosion
3566 if( bashed_item->made_of( material_id( "glass" ) ) && !bashed_item->active && one_in( 2 ) ) {
3567 result.did_bash = true;
3568 smashed_glass = true;
3569 for( const item *bashed_content : bashed_item->contents.all_items_top() ) {
3570 smashed_contents.push_back( item( *bashed_content ) );
3571 }
3572 bashed_item = bashed_items.erase( bashed_item );
3573 } else {
3574 ++bashed_item;
3575 }
3576 }
3577 // Now plunk in the contents of the smashed items.
3578 spawn_items( p, smashed_contents );
3579
3580 // Add a glass sound even when something else also breaks
3581 if( smashed_glass && !params.silent ) {
3582 sounds::sound( p, 12, sounds::sound_t::combat, _( "glass shattering" ), false,
3583 "smash_success", "smash_glass_contents" );
3584 }
3585 return result;
3586}
std::list< item * > all_items_top()
returns a list of pointers to all top-level items
item_contents contents
Definition: item.h:2158
bool has_items(const tripoint &p) const
Checks for existence of items.
Definition: map.cpp:4760

References _, item_contents::all_items_top(), sounds::combat, item::contents, has_items(), i_at(), one_in(), bash_params::silent, sounds::sound(), and spawn_items().

Referenced by bash().

◆ bash_rating() [1/2]

int map::bash_rating ( const int  str,
const point p 
) const
inline

Definition at line 1053 of file map.h.

1053 {
1054 return bash_rating( str, tripoint( p, abs_sub.z ) );
1055 }
int bash_rating(int str, const tripoint &p, bool allow_floor=false) const
Returns a success rating from -1 to 10 for a given tile based on a set strength, used for AI movement...
Definition: map.cpp:2477

References abs_sub, bash_rating(), and tripoint::z.

◆ bash_rating() [2/2]

int map::bash_rating ( int  str,
const tripoint p,
bool  allow_floor = false 
) const

Returns a success rating from -1 to 10 for a given tile based on a set strength, used for AI movement planning Values roughly correspond to 10% increment chances of success on a given bash, rounded down.

-1 means the square is not bashable

Definition at line 2477 of file map.cpp.

2478{
2479 if( !inbounds( p ) ) {
2480 dbg( DL::Warn ) << "Looking for out-of-bounds is_bashable at " << p;
2481 return -1;
2482 }
2483
2484 if( str <= 0 ) {
2485 return -1;
2486 }
2487
2488 const furn_t &furniture = furn( p ).obj();
2489 const ter_t &terrain = ter( p ).obj();
2490 const optional_vpart_position vp = veh_at( p );
2491 vehicle *const veh = vp ? &vp->vehicle() : nullptr;
2492 const int part = vp ? vp->part_index() : -1;
2493 return bash_rating_internal( str, furniture, terrain, allow_floor, veh, part );
2494}
int bash_rating_internal(int str, const furn_t &furniture, const ter_t &terrain, bool allow_floor, const vehicle *veh, int part) const
Definition: map.cpp:2369

References bash_rating_internal(), dbg, furn(), furniture, inbounds(), int_id< T >::obj(), ter(), terrain, veh_at(), and Warn.

Referenced by bash_rating(), npc::can_move_to(), monster::move(), and npc::move_to().

◆ bash_rating_internal()

int map::bash_rating_internal ( int  str,
const furn_t furniture,
const ter_t terrain,
bool  allow_floor,
const vehicle veh,
int  part 
) const
private
Strength determines what furniture can be smashed Strength determines what terrain can be smashed Strength increases smashing damage

Definition at line 2369 of file map.cpp.

2372{
2373 bool furn_smash = false;
2374 bool ter_smash = false;
2375 ///\EFFECT_STR determines what furniture can be smashed
2376 if( furniture.id && furniture.bash.str_max != -1 ) {
2377 furn_smash = true;
2378 ///\EFFECT_STR determines what terrain can be smashed
2379 } else if( terrain.bash.str_max != -1 && ( !terrain.bash.bash_below || allow_floor ) ) {
2380 ter_smash = true;
2381 }
2382
2383 if( veh != nullptr && vpart_position( const_cast<vehicle &>( *veh ), part ).obstacle_at_part() ) {
2384 // Monsters only care about rating > 0, NPCs should want to path around cars instead
2385 return 2; // Should probably be a function of part hp (+armor on tile)
2386 }
2387
2388 int bash_min = 0;
2389 int bash_max = 0;
2390 if( furn_smash ) {
2391 bash_min = furniture.bash.str_min;
2392 bash_max = furniture.bash.str_max;
2393 } else if( ter_smash ) {
2394 bash_min = terrain.bash.str_min;
2395 bash_max = terrain.bash.str_max;
2396 } else {
2397 return -1;
2398 }
2399
2400 ///\EFFECT_STR increases smashing damage
2401 if( str < bash_min ) {
2402 return 0;
2403 } else if( str >= bash_max ) {
2404 return 10;
2405 }
2406
2407 int ret = ( 10 * ( str - bash_min ) ) / ( bash_max - bash_min );
2408 // Round up to 1, so that desperate NPCs can try to bash down walls
2409 return std::max( ret, 1 );
2410}
Reference to a position (a point) of the vehicle.

References furniture, cata::hash64_detail::ret, and terrain.

Referenced by bash_rating(), and route().

◆ bash_resistance() [1/2]

int map::bash_resistance ( const point p) const
inline

Definition at line 1047 of file map.h.

1047 {
1048 return bash_resistance( tripoint( p, abs_sub.z ) );
1049 }
int bash_resistance(const tripoint &p, bool allow_floor=false) const
Returns min_str of the furniture or terrain at p.
Definition: map.cpp:2463

References abs_sub, bash_resistance(), and tripoint::z.

◆ bash_resistance() [2/2]

int map::bash_resistance ( const tripoint p,
bool  allow_floor = false 
) const

Returns min_str of the furniture or terrain at p.

Definition at line 2463 of file map.cpp.

2464{
2465 if( has_furn( p ) && furn( p ).obj().bash.str_min != -1 ) {
2466 return furn( p ).obj().bash.str_min;
2467 }
2468
2469 const auto &ter_bash = ter( p ).obj().bash;
2470 if( ter_bash.str_min != -1 && ( !ter_bash.bash_below || allow_floor ) ) {
2471 return ter_bash.str_min;
2472 }
2473
2474 return -1;
2475}
bool has_furn(const tripoint &p) const
Definition: map.cpp:1343
int str_min
Definition: mapdata.h:62

References bash(), map_data_common_t::bash, furn(), has_furn(), int_id< T >::obj(), map_bash_info::str_min, and ter().

Referenced by bash_resistance(), ranged::expected_coverage(), vehicle::part_collision(), rate_location(), smash(), and terrain_collision_data().

◆ bash_strength() [1/2]

int map::bash_strength ( const point p) const
inline

Definition at line 1042 of file map.h.

1042 {
1043 return bash_strength( tripoint( p, abs_sub.z ) );
1044 }
int bash_strength(const tripoint &p, bool allow_floor=false) const
Returns max_str of the furniture or terrain at p.
Definition: map.cpp:2449

References abs_sub, bash_strength(), and tripoint::z.

◆ bash_strength() [2/2]

int map::bash_strength ( const tripoint p,
bool  allow_floor = false 
) const

Returns max_str of the furniture or terrain at p.

Definition at line 2449 of file map.cpp.

2450{
2451 if( has_furn( p ) && furn( p ).obj().bash.str_max != -1 ) {
2452 return furn( p ).obj().bash.str_max;
2453 }
2454
2455 const auto &ter_bash = ter( p ).obj().bash;
2456 if( ter_bash.str_max != -1 && ( !ter_bash.bash_below || allow_floor ) ) {
2457 return ter_bash.str_max;
2458 }
2459
2460 return -1;
2461}
int str_max
Definition: mapdata.h:64

References bash(), map_data_common_t::bash, furn(), has_furn(), int_id< T >::obj(), map_bash_info::str_max, and ter().

Referenced by bash_strength(), ranged::expected_coverage(), game::fling_creature(), and terrain_collision_data().

◆ bash_ter_furn()

bash_results map::bash_ter_furn ( const tripoint p,
const bash_params params 
)

Definition at line 3392 of file map.cpp.

3393{
3395 std::string soundfxvariant;
3396 const auto &ter_obj = ter( p ).obj();
3397 const auto &furn_obj = furn( p ).obj();
3398 bool smash_ter = false;
3399 const map_bash_info *bash = nullptr;
3400
3401 if( furn_obj.id && furn_obj.bash.str_max != -1 ) {
3402 bash = &furn_obj.bash;
3403 soundfxvariant = furn_obj.id.str();
3404 } else if( ter_obj.bash.str_max != -1 ) {
3405 bash = &ter_obj.bash;
3406 smash_ter = true;
3407 soundfxvariant = ter_obj.id.str();
3408 }
3409
3410 // Floor bashing check
3411 // Only allow bashing floors when we want to bash floors and we're in z-level mode
3412 // Unless we're destroying, then it gets a little weird
3413 if( smash_ter && bash->bash_below && ( !zlevels || !params.bash_floor ) ) {
3414 if( !params.destroy ) {
3415 smash_ter = false;
3416 bash = nullptr;
3417 } else if( !bash->ter_set && zlevels ) {
3418 // HACK: A hack for destroy && !bash_floor
3419 // We have to check what would we create and cancel if it is what we have now
3420 tripoint below( p.xy(), p.z - 1 );
3421 const auto roof = get_roof( below, false );
3422 if( roof == ter( p ) ) {
3423 smash_ter = false;
3424 bash = nullptr;
3425 }
3426 } else if( !bash->ter_set && ter( p ) == t_dirt ) {
3427 // As above, except for no-z-levels case
3428 smash_ter = false;
3429 bash = nullptr;
3430 }
3431 }
3432
3433 // TODO: what if silent is true?
3434 if( has_flag( "ALARMED", p ) && !g->timed_events.queued( TIMED_EVENT_WANTED ) ) {
3435 sounds::sound( p, 40, sounds::sound_t::alarm, _( "an alarm go off!" ),
3436 false, "environment", "alarm" );
3437 // Blame nearby player
3438 if( rl_dist( g->u.pos(), p ) <= 3 ) {
3439 g->events().send<event_type::triggers_alarm>( g->u.getID() );
3440 const point abs = ms_to_sm_copy( getabs( p.xy() ) );
3441 g->timed_events.add( TIMED_EVENT_WANTED, calendar::turn + 30_minutes, 0,
3442 tripoint( abs, p.z ) );
3443 }
3444 }
3445
3446 if( bash == nullptr || ( bash->destroy_only && !params.destroy ) ) {
3447 // Nothing bashable here
3448 if( impassable( p ) ) {
3449 if( !params.silent ) {
3450 sounds::sound( p, 18, sounds::sound_t::combat, _( "thump!" ),
3451 false, "smash_fail", "default" );
3452 }
3453
3454 result.did_bash = true;
3455 result.bashed_solid = true;
3456 }
3457
3458 return result;
3459 }
3460
3461 result.did_bash = true;
3462 result.bashed_solid = true;
3463 result.success = params.destroy;
3464
3465 int smin = bash->str_min;
3466 int smax = bash->str_max;
3467 if( !params.destroy ) {
3468 if( bash->str_min_blocked != -1 || bash->str_max_blocked != -1 ) {
3469 if( furn_is_supported( *this, p ) ) {
3470 if( bash->str_min_blocked != -1 ) {
3471 smin = bash->str_min_blocked;
3472 }
3473 if( bash->str_max_blocked != -1 ) {
3474 smax = bash->str_max_blocked;
3475 }
3476 }
3477 }
3478
3479 if( bash->str_min_supported != -1 || bash->str_max_supported != -1 ) {
3480 tripoint below( p.xy(), p.z - 1 );
3481 if( !zlevels || has_flag( TFLAG_SUPPORTS_ROOF, below ) ) {
3482 if( bash->str_min_supported != -1 ) {
3483 smin = bash->str_min_supported;
3484 }
3485 if( bash->str_max_supported != -1 ) {
3486 smax = bash->str_max_supported;
3487 }
3488 }
3489 }
3490 // Linear interpolation from str_min to str_max
3491 const int resistance = smin + ( params.roll * ( smax - smin ) );
3492 if( params.strength >= resistance ) {
3493 result.success = true;
3494 }
3495 }
3496
3497 if( !result.success ) {
3498 int sound_volume = bash->sound_fail_vol.value_or( 12 );
3499
3500 result.did_bash = true;
3501 if( !params.silent ) {
3502 sounds::sound( p, sound_volume, sounds::sound_t::combat, bash->sound_fail, false,
3503 "smash_fail", soundfxvariant );
3504 }
3505 } else {
3506 if( smash_ter ) {
3507 result |= bash_ter_success( p, params );
3508 } else {
3509 result |= bash_furn_success( p, params );
3510 }
3511 }
3512
3513 return result;
3514}
ter_id get_roof(const tripoint &p, bool allow_air) const
Definition: map.cpp:3094
bash_results bash_furn_success(const tripoint &p, const bash_params &params)
Definition: map.cpp:3292
bash_results bash_ter_success(const tripoint &p, const bash_params &params)
Definition: map.cpp:3162
point ms_to_sm_copy(const point &p)
static bool furn_is_supported(const map &m, const tripoint &p)
Definition: map.cpp:3138
ter_id t_dirt
Definition: mapdata.cpp:625
@ TFLAG_SUPPORTS_ROOF
Definition: mapdata.h:280
float roll
Value from 0.0 to 1.0 that affects interpolation between str_min and str_max At 0....
Definition: map.h:147
bool bash_floor
Definition: map.h:140
bool destroy
Definition: map.h:138
int strength
Definition: map.h:134
@ TIMED_EVENT_WANTED
Definition: timed_event.h:13

References _, sounds::alarm, bash(), bash_params::bash_floor, bash_furn_success(), bash_ter_success(), sounds::combat, bash_params::destroy, furn(), furn_is_supported(), g, get_roof(), getabs(), has_flag(), impassable(), ms_to_sm_copy(), int_id< T >::obj(), rl_dist(), bash_params::roll, bash_params::silent, sounds::sound(), bash_params::strength, t_dirt, ter(), TFLAG_SUPPORTS_ROOF, TIMED_EVENT_WANTED, triggers_alarm, calendar::turn, tripoint::xy(), tripoint::z, and zlevels.

Referenced by bash(), bash_ter_success(), and explosion_handler::do_blast_new().

◆ bash_ter_success()

bash_results map::bash_ter_success ( const tripoint p,
const bash_params params 
)

Definition at line 3162 of file map.cpp.

3163{
3165 result.success = true;
3166 const ter_t &ter_before = ter( p ).obj();
3167 const map_bash_info &bash = ter_before.bash;
3168 if( has_flag_ter( "FUNGUS", p ) ) {
3169 fungal_effects( *g, *this ).create_spores( p );
3170 }
3171 const std::string soundfxvariant = ter_before.id.str();
3172 const bool will_collapse = ter_before.has_flag( TFLAG_SUPPORTS_ROOF ) &&
3173 !ter_before.has_flag( TFLAG_INDOORS );
3174 const bool suspended = ter_before.has_flag( TFLAG_SUSPENDED );
3175 bool follow_below = false;
3176 if( params.bashing_from_above && bash.ter_set_bashed_from_above ) {
3177 // If this terrain is being bashed from above and this terrain
3178 // has a valid post-destroy bashed-from-above terrain, set it
3179 ter_set( p, bash.ter_set_bashed_from_above );
3180 } else if( bash.ter_set ) {
3181 // If the terrain has a valid post-destroy terrain, set it
3182 ter_set( p, bash.ter_set );
3183 follow_below |= zlevels && bash.bash_below;
3184 } else if( suspended ) {
3185 // Its important that we change the ter value before recursing, otherwise we'll hit an infinite loop.
3186 // This could be prevented by assembling a visited list, but in order to avoid that cost, we're going
3187 // build our recursion to just be resilient.
3188 ter_set( p, t_open_air );
3190 } else {
3191 tripoint below( p.xy(), p.z - 1 );
3192 const ter_t &ter_below = ter( below ).obj();
3193 // Only setting the flag here because we want drops and sounds in correct order
3194 follow_below |= zlevels && bash.bash_below && ter_below.roof;
3195
3196 ter_set( p, t_open_air );
3197 }
3198
3200
3201 if( !bash.sound.empty() && !params.silent ) {
3202 static const std::string soundfxid = "smash_success";
3203 int sound_volume = get_sound_volume( bash );
3204 sounds::sound( p, sound_volume, sounds::sound_t::combat, bash.sound, false,
3205 soundfxid, soundfxvariant );
3206 }
3207
3208 if( !zlevels ) {
3209 if( ter( p ) == t_open_air ) {
3210 // We destroyed something, so we aren't just "plugging" air with dirt here
3211 ter_set( p, t_dirt );
3212 }
3213 } else if( follow_below || ter( p ) == t_open_air ) {
3214 const tripoint below( p.xy(), p.z - 1 );
3215 // We may need multiple bashes in some weird cases
3216 // Example:
3217 // W has roof A
3218 // A bashes to B
3219 // B bashes to nothing
3220 // Below our point P, there is a W
3221 // If we bash down a B over a W, it might be from earlier A or just constructed over it!
3222 //
3223 // Current solution: bash roof until you reach same roof type twice, then bash down
3224 if( follow_below && params.do_recurse ) {
3225 bool blocked_by_roof = false;
3226 std::set<ter_id> encountered_types;
3227 encountered_types.insert( ter_before.id );
3228 encountered_types.insert( t_open_air );
3229 // Note: we're bashing the new roof, not the tile supported by it!
3230 int down_bash_tries = 10;
3231 do {
3232 const ter_id &ter_now = ter( p );
3233 if( encountered_types.count( ter_now ) != 0 ) {
3234 // We have encountered this type before and destroyed it (didn't block us)
3235 ter_set( p, t_open_air );
3236 bash_params params_below = params;
3237 params_below.bashing_from_above = true;
3238 params_below.bash_floor = false;
3239 params_below.do_recurse = false;
3240 params_below.destroy = true;
3241 int impassable_bash_tries = 10;
3242 // Unconditionally destroy, but don't go deeper
3243 do {
3244 result |= bash_ter_success( below, params_below );
3245 } while( ter( below )->movecost == 0 && impassable_bash_tries-- > 0 );
3246 if( impassable_bash_tries <= 0 ) {
3247 debugmsg( "Loop in terrain bashing for type %s", ter_before.id.str() );
3248 }
3249 } else if( ter_now == t_open_air ) {
3250 const ter_id &roof = get_roof( below, params.bash_floor && ter( below )->movecost != 0 );
3251 if( roof != t_open_air ) {
3252 ter_set( p, roof );
3253 }
3254 } else {
3255 // This floor/roof tile wasn't destroyed in this loop yet
3256 encountered_types.insert( ter_now );
3257 bash_params params_copy = params;
3258 params_copy.do_recurse = false;
3259 // TODO: Unwrap the calls, don't recurse
3260 // TODO: Don't bash furn
3261 bash_results results_sub = bash_ter_furn( p, params_copy );
3262 result |= results_sub;
3263 if( !results_sub.success ) {
3264 // Blocked, as in "the roof was too strong to bash"
3265 blocked_by_roof = true;
3266 }
3267 }
3268 } while( down_bash_tries-- > 0 && !blocked_by_roof &&
3269 ( ter( p ) != t_open_air || ter( p )->movecost == 0 || ter( below )->roof ) );
3270 if( down_bash_tries <= 0 ) {
3271 debugmsg( "Loop in terrain bashing for type %s", ter_before.id.str() );
3272 }
3273 } else {
3274 const ter_id &roof = get_roof( below, params.bash_floor && ter( below )->movecost != 0 );
3275
3276 ter_set( p, roof );
3277 }
3278 }
3279
3280 if( will_collapse && !has_flag( TFLAG_SUPPORTS_ROOF, p ) ) {
3281 collapse_at( p, params.silent, true, bash.explosive > 0 );
3282 }
3283
3284 if( bash.explosive > 0 ) {
3285 // TODO Implement if the player triggered the explosive terrain
3286 explosion_handler::explosion( p, nullptr, bash.explosive, 0.8, false );
3287 }
3288
3289 return result;
3290}
void propagate_suspension_check(const tripoint &point)
Checks surrounding tiles for suspension, and has them check for collapse.
Definition: map.cpp:2943
void collapse_at(const tripoint &p, bool silent, bool was_supporting=false, bool destroy_pos=true)
Causes a collapse at p, such as from destroying a wall.
Definition: map.cpp:2898
const std::string & str() const
Returns the identifier as plain std::string.
Definition: string_id.h:255
@ TFLAG_SUSPENDED
Definition: mapdata.h:323
@ TFLAG_INDOORS
Definition: mapdata.h:291
bool do_recurse
Hack to prevent infinite recursion.
Definition: map.h:159
bool bashing_from_above
Definition: map.h:154
bool success
Definition: map.h:170
bool has_flag(const std::string &flag) const
Definition: mapdata.h:415
ter_str_id id
Definition: mapdata.h:461

References bash(), map_data_common_t::bash, bash_params::bash_floor, bash_ter_furn(), bash_ter_success(), bash_params::bashing_from_above, collapse_at(), sounds::combat, fungal_effects::create_spores(), debugmsg, bash_params::destroy, bash_params::do_recurse, explosion_handler::explosion(), g, get_roof(), get_sound_volume(), map_data_common_t::has_flag(), has_flag(), has_flag_ter(), ter_t::id, item_group::items_from(), int_id< T >::obj(), propagate_suspension_check(), ter_t::roof, bash_params::silent, sounds::sound(), spawn_items(), string_id< T >::str(), bash_results::success, t_dirt, t_open_air, ter(), ter_set(), TFLAG_INDOORS, TFLAG_SUPPORTS_ROOF, TFLAG_SUSPENDED, calendar::turn, tripoint::xy(), tripoint::z, and zlevels.

Referenced by bash_ter_furn(), bash_ter_success(), and shoot().

◆ bash_vehicle()

bash_results map::bash_vehicle ( const tripoint p,
const bash_params params 
)

Definition at line 3588 of file map.cpp.

3589{
3591 // Smash vehicle if present
3592 if( const optional_vpart_position vp = veh_at( p ) ) {
3593 vp->vehicle().damage( vp->part_index(), params.strength, DT_BASH );
3594 if( !params.silent ) {
3595 sounds::sound( p, 18, sounds::sound_t::combat, _( "crash!" ), false,
3596 "smash_success", "hit_vehicle" );
3597 }
3598
3599 result.did_bash = true;
3600 result.success = true;
3601 result.bashed_solid = true;
3602 }
3603 return result;
3604}
@ DT_BASH
Definition: damage.h:24

References _, sounds::combat, DT_BASH, bash_params::silent, sounds::sound(), bash_params::strength, and veh_at().

Referenced by bash().

◆ batter()

void map::batter ( const tripoint p,
int  power,
int  tries = 1,
bool  silent = false 
)

bash a square for a set number of times at set power.

Does not destroy

Definition at line 3653 of file map.cpp.

3654{
3655 int count = 0;
3656 while( count < tries && bash( p, power, silent ).success ) {
3657 count++;
3658 }
3659}
@ success
Definition: behavior.h:20

References bash(), detail::count(), silent, and behavior::success.

Referenced by activity_handlers::chop_tree_finish().

◆ board_vehicle()

void map::board_vehicle ( const tripoint p,
player pl 
)

Definition at line 1049 of file map.cpp.

1050{
1051 if( p == nullptr ) {
1052 debugmsg( "map::board_vehicle: null player" );
1053 return;
1054 }
1055
1057 true );
1058 if( !vp ) {
1059 if( p->grab_point.x == 0 && p->grab_point.y == 0 ) {
1060 debugmsg( "map::board_vehicle: vehicle not found" );
1061 }
1062 return;
1063 }
1064 if( vp->part().has_flag( vehicle_part::passenger_flag ) ) {
1065 player *psg = vp->vehicle().get_passenger( vp->part_index() );
1066 debugmsg( "map::board_vehicle: passenger (%s) is already there",
1067 psg ? psg->name : "<null>" );
1068 unboard_vehicle( pos );
1069 }
1070 vp->part().set_flag( vehicle_part::passenger_flag );
1071 vp->part().passenger_id = p->getID();
1072 vp->vehicle().invalidate_mass();
1073
1074 p->setpos( pos );
1075 p->in_vehicle = true;
1076 if( p->is_avatar() ) {
1077 g->update_map( g->u );
1078 }
1079}
std::string name
Definition: character.h:1504
void unboard_vehicle(const vpart_reference &, Character *passenger, bool dead_passenger=false)
Definition: map.cpp:1081
cata::optional< vpart_reference > part_with_feature(const std::string &f, bool unbroken) const
Definition: vehicle.cpp:2481
Definition: player.h:91
@ passenger_flag
Definition: vehicle.h:192
@ VPFLAG_BOARDABLE
Definition: veh_type.h:39

References debugmsg, g, Character::getID(), player::grab_point, Character::in_vehicle, Creature::is_avatar(), Character::name, optional_vpart_position::part_with_feature(), vehicle_part::passenger_flag, wrapped_vehicle::pos, Character::setpos(), unboard_vehicle(), veh_at(), VPFLAG_BOARDABLE, tripoint::x, and tripoint::y.

Referenced by debug_menu::debug(), npc::move_to(), game::phasing_move(), game::place_player(), game::swap_critters(), and avatar_action::swim().

◆ build_floor_cache()

bool map::build_floor_cache ( int  zlev)

Definition at line 8001 of file map.cpp.

8002{
8003 auto &ch = get_cache( zlev );
8004 if( !ch.floor_cache_dirty ) {
8005 return false;
8006 }
8007
8008 auto &floor_cache = ch.floor_cache;
8009 std::uninitialized_fill_n(
8010 &floor_cache[0][0], ( MAPSIZE_X ) * ( MAPSIZE_Y ), true );
8011
8012 bool lowest_z_lev = zlev <= -OVERMAP_DEPTH;
8013 for( int smx = 0; smx < my_MAPSIZE; ++smx ) {
8014 for( int smy = 0; smy < my_MAPSIZE; ++smy ) {
8015 const submap *cur_submap = get_submap_at_grid( { smx, smy, zlev } );
8016 const submap *below_submap = !lowest_z_lev ? get_submap_at_grid( { smx, smy, zlev - 1 } ) : nullptr;
8017
8018 if( cur_submap == nullptr ) {
8019 debugmsg( "Tried to build floor cache at (%d,%d,%d) but the submap is not loaded", smx, smy, zlev );
8020 continue;
8021 }
8022 if( !lowest_z_lev && below_submap == nullptr ) {
8023 debugmsg( "Tried to build floor cache at (%d,%d,%d) but the submap is not loaded", smx, smy,
8024 zlev - 1 );
8025 continue;
8026 }
8027
8028 for( int sx = 0; sx < SEEX; ++sx ) {
8029 for( int sy = 0; sy < SEEY; ++sy ) {
8030 point sp( sx, sy );
8031 const ter_t &terrain = cur_submap->get_ter( sp ).obj();
8032 if( terrain.has_flag( TFLAG_NO_FLOOR ) ) {
8033 if( below_submap && ( below_submap->get_furn( sp ).obj().has_flag( TFLAG_SUN_ROOF_ABOVE ) ) ) {
8034 continue;
8035 }
8036 const int x = sx + smx * SEEX;
8037 const int y = sy + smy * SEEY;
8038 floor_cache[x][y] = false;
8039 }
8040 }
8041 }
8042 }
8043 }
8044
8045 ch.floor_cache_dirty = false;
8046 return zlevels;
8047}
@ TFLAG_SUN_ROOF_ABOVE
Definition: mapdata.h:322
@ TFLAG_NO_FLOOR
Definition: mapdata.h:310
static const int sx[4]
Definition: tileray.cpp:10
static const int sy[4]
Definition: tileray.cpp:11

References debugmsg, get_cache(), get_submap_at_grid(), submap::get_ter(), MAPSIZE_X, MAPSIZE_Y, my_MAPSIZE, int_id< T >::obj(), OVERMAP_DEPTH, SEEX, SEEY, sx, sy, terrain, TFLAG_NO_FLOOR, TFLAG_SUN_ROOF_ABOVE, and zlevels.

Referenced by build_floor_caches(), and build_map_cache().

◆ build_floor_caches()

void map::build_floor_caches ( )

Definition at line 8049 of file map.cpp.

8050{
8051 const int minz = zlevels ? -OVERMAP_DEPTH : abs_sub.z;
8052 const int maxz = zlevels ? OVERMAP_HEIGHT : abs_sub.z;
8053 for( int z = minz; z <= maxz; z++ ) {
8054 build_floor_cache( z );
8055 }
8056}
bool build_floor_cache(int zlev)
Definition: map.cpp:8001

References abs_sub, build_floor_cache(), OVERMAP_DEPTH, OVERMAP_HEIGHT, tripoint::z, and zlevels.

Referenced by game::do_turn().

◆ build_map_cache()

void map::build_map_cache ( int  zlev,
bool  skip_lightmap = false 
)

Definition at line 8215 of file map.cpp.

8216{
8217 const int minz = zlevels ? -OVERMAP_DEPTH : zlev;
8218 const int maxz = zlevels ? OVERMAP_HEIGHT : zlev;
8219 bool seen_cache_dirty = false;
8220 for( int z = minz; z <= maxz; z++ ) {
8221 // trigger FOV recalculation only when there is a change on the player's level or if fov_3d is enabled
8222 const bool affects_seen_cache = z == zlev || fov_3d;
8226 seen_cache_dirty |= ( build_floor_cache( z ) && affects_seen_cache );
8227 seen_cache_dirty |= get_cache( z ).seen_cache_dirty && affects_seen_cache;
8228 diagonal_blocks fill = {false, false};
8229 std::uninitialized_fill_n( &( get_cache( z ).vehicle_obscured_cache[0][0] ), MAPSIZE_X * MAPSIZE_Y,
8230 fill );
8231 std::uninitialized_fill_n( &( get_cache( z ).vehicle_obstructed_cache[0][0] ),
8233 }
8234 // needs a separate pass as it changes the caches on neighbour z-levels (e.g. floor_cache);
8235 // otherwise such changes might be overwritten by main cache-building logic
8236 for( int z = minz; z <= maxz; z++ ) {
8237 do_vehicle_caching( z );
8238 }
8239 for( int z = minz; z <= maxz; z++ ) {
8240 seen_cache_dirty |= build_vision_transparency_cache( z );
8241 }
8242
8243 if( seen_cache_dirty ) {
8244 skew_vision_cache.clear();
8245 }
8246 // Initial value is illegal player position.
8247 const tripoint &p = g->u.pos();
8248 static tripoint player_prev_pos;
8249 if( seen_cache_dirty || player_prev_pos != p ) {
8250 build_seen_cache( p, zlev );
8251 player_prev_pos = p;
8252 }
8253 if( !skip_lightmap ) {
8254 generate_lightmap( zlev );
8255 }
8256}
bool fov_3d
3D FoV enabled/disabled.
void build_outside_cache(int zlev)
Definition: map.cpp:7894
void update_suspension_cache(const int &z)
Definition: map.cpp:8058
void do_vehicle_caching(int z)
Definition: map.cpp:8198
void build_seen_cache(const tripoint &origin, int target_z)
Calculates the Field Of View for the provided map from the given x, y coordinates.
Definition: lightmap.cpp:1292
lru_cache< point, char > skew_vision_cache
Cache of coordinate pairs recently checked for visibility.
Definition: map.h:2018
bool build_transparency_cache(int zlev)
Definition: lightmap.cpp:81
void generate_lightmap(int zlev)
Definition: lightmap.cpp:371
bool build_vision_transparency_cache(int zlev)
Definition: lightmap.cpp:167
FMT_NOINLINE OutputIt fill(OutputIt it, size_t n, const fill_t< Char > &fill)
bool seen_cache_dirty
Definition: map.h:309

References build_floor_cache(), build_outside_cache(), build_seen_cache(), build_transparency_cache(), build_vision_transparency_cache(), do_vehicle_caching(), detail::fill(), fov_3d, g, generate_lightmap(), get_cache(), MAPSIZE_X, MAPSIZE_Y, OVERMAP_DEPTH, OVERMAP_HEIGHT, level_cache::seen_cache_dirty, skew_vision_cache, update_suspension_cache(), and zlevels.

Referenced by game::do_turn(), game::draw(), game::look_around(), start_location::place_player(), game::start_game(), and game::update_map().

◆ build_obstacle_cache()

void map::build_obstacle_cache ( const tripoint start,
const tripoint end,
float(&)  obstacle_cache[MAPSIZE_X][MAPSIZE_Y] 
)

Definition at line 7948 of file map.cpp.

7950{
7951 const point min_submap{ std::max( 0, start.x / SEEX ), std::max( 0, start.y / SEEY ) };
7952 const point max_submap{
7953 std::min( my_MAPSIZE - 1, end.x / SEEX ), std::min( my_MAPSIZE - 1, end.y / SEEY ) };
7954 // Find and cache all the map obstacles.
7955 // For now setting obstacles to be extremely dense and fill their squares.
7956 // In future, scale effective obstacle density by the thickness of the obstacle.
7957 // Also consider modelling partial obstacles.
7958 // TODO: Support z-levels.
7959 for( int smx = min_submap.x; smx <= max_submap.x; ++smx ) {
7960 for( int smy = min_submap.y; smy <= max_submap.y; ++smy ) {
7961 const auto cur_submap = get_submap_at_grid( { smx, smy, start.z } );
7962
7963 // TODO: Init indices to prevent iterating over unused submap sections.
7964 for( int sx = 0; sx < SEEX; ++sx ) {
7965 for( int sy = 0; sy < SEEY; ++sy ) {
7966 const point sp( sx, sy );
7967 int ter_move = cur_submap->get_ter( sp ).obj().movecost;
7968 int furn_move = cur_submap->get_furn( sp ).obj().movecost;
7969 const int x = sx + smx * SEEX;
7970 const int y = sy + smy * SEEY;
7971 if( ter_move == 0 || furn_move < 0 || ter_move + furn_move == 0 ) {
7972 obstacle_cache[x][y] = 1000.0f;
7973 } else {
7974 obstacle_cache[x][y] = 0.0f;
7975 }
7976 }
7977 }
7978 }
7979 }
7980 VehicleList vehs = get_vehicles( start, end );
7981 const inclusive_cuboid<tripoint> bounds( start, end );
7982 // Cache all the vehicle stuff in one loop
7983 for( auto &v : vehs ) {
7984 for( const vpart_reference &vp : v.v->get_all_parts() ) {
7985 tripoint p = v.pos + vp.part().precalc[0];
7986 if( p.z != start.z ) {
7987 break;
7988 }
7989 if( !bounds.contains( p ) ) {
7990 continue;
7991 }
7992
7993 if( vp.obstacle_at_part() ) {
7994 obstacle_cache[p.x][p.y] = 1000.0f;
7995 }
7996 }
7997 }
7998
7999}
VehicleList get_vehicles()
Definition: map.cpp:237
std::vector< wrapped_vehicle > VehicleList
Definition: map.h:85

References inclusive_cuboid< Tripoint, >::contains(), get_submap_at_grid(), get_vehicles(), my_MAPSIZE, SEEX, SEEY, sx, sy, tripoint::x, tripoint::y, and tripoint::z.

Referenced by explosion_handler::shrapnel().

◆ build_outside_cache()

void map::build_outside_cache ( int  zlev)

Definition at line 7894 of file map.cpp.

7895{
7896 auto &ch = get_cache( zlev );
7897 if( !ch.outside_cache_dirty ) {
7898 return;
7899 }
7900
7901 // Make a bigger cache to avoid bounds checking
7902 // We will later copy it to our regular cache
7903 const size_t padded_w = ( MAPSIZE_X ) + 2;
7904 const size_t padded_h = ( MAPSIZE_Y ) + 2;
7905 bool padded_cache[padded_w][padded_h];
7906
7907 auto &outside_cache = ch.outside_cache;
7908 if( zlev < 0 ) {
7909 std::uninitialized_fill_n(
7910 &outside_cache[0][0], ( MAPSIZE_X ) * ( MAPSIZE_Y ), false );
7911 return;
7912 }
7913
7914 std::uninitialized_fill_n(
7915 &padded_cache[0][0], padded_w * padded_h, true );
7916
7917 for( int smx = 0; smx < my_MAPSIZE; ++smx ) {
7918 for( int smy = 0; smy < my_MAPSIZE; ++smy ) {
7919 const auto cur_submap = get_submap_at_grid( { smx, smy, zlev } );
7920
7921 for( int sx = 0; sx < SEEX; ++sx ) {
7922 for( int sy = 0; sy < SEEY; ++sy ) {
7923 point sp( sx, sy );
7924 if( cur_submap->get_ter( sp ).obj().has_flag( TFLAG_INDOORS ) ||
7925 cur_submap->get_furn( sp ).obj().has_flag( TFLAG_INDOORS ) ) {
7926 const int x = sx + smx * SEEX;
7927 const int y = sy + smy * SEEY;
7928 // Add 1 to both coordinates, because we're operating on the padded cache
7929 for( int dx = 0; dx <= 2; dx++ ) {
7930 for( int dy = 0; dy <= 2; dy++ ) {
7931 padded_cache[x + dx][y + dy] = false;
7932 }
7933 }
7934 }
7935 }
7936 }
7937 }
7938 }
7939
7940 // Copy the padded cache back to the proper one, but with no padding
7941 for( int x = 0; x < SEEX * my_MAPSIZE; x++ ) {
7942 std::copy_n( &padded_cache[x + 1][1], SEEX * my_MAPSIZE, &outside_cache[x][0] );
7943 }
7944
7945 ch.outside_cache_dirty = false;
7946}

References get_cache(), get_submap_at_grid(), MAPSIZE_X, MAPSIZE_Y, my_MAPSIZE, SEEX, SEEY, sx, sy, and TFLAG_INDOORS.

Referenced by build_map_cache(), start_location::burn(), and start_location::prepare_map().

◆ build_seen_cache()

void map::build_seen_cache ( const tripoint origin,
int  target_z 
)
protected

Calculates the Field Of View for the provided map from the given x, y coordinates.

Returns a lightmap for a result where the values represent a percentage of fully lit.

A value equal to or below 0 means that cell is not in the field of view, whereas a value equal to or above 1 means that cell is in the field of view.

Parameters
originthe starting location
target_zZ-level to draw light map on

Definition at line 1292 of file lightmap.cpp.

1293{
1294 auto &map_cache = get_cache( target_z );
1295 float ( &transparency_cache )[MAPSIZE_X][MAPSIZE_Y] = map_cache.vision_transparency_cache;
1296 float ( &seen_cache )[MAPSIZE_X][MAPSIZE_Y] = map_cache.seen_cache;
1297 float ( &camera_cache )[MAPSIZE_X][MAPSIZE_Y] = map_cache.camera_cache;
1298 diagonal_blocks( &blocked_cache )[MAPSIZE_X][MAPSIZE_Y] = map_cache.vehicle_obscured_cache;
1299
1300 constexpr float light_transparency_solid = LIGHT_TRANSPARENCY_SOLID;
1301 constexpr int map_dimensions = MAPSIZE_X * MAPSIZE_Y;
1302 std::uninitialized_fill_n(
1303 &camera_cache[0][0], map_dimensions, light_transparency_solid );
1304
1305 if( !fov_3d ) {
1306 for( int z = -OVERMAP_DEPTH; z <= OVERMAP_HEIGHT; z++ ) {
1307 auto &cur_cache = get_cache( z );
1308 if( z == target_z || cur_cache.seen_cache_dirty ) {
1309 std::uninitialized_fill_n(
1310 &cur_cache.seen_cache[0][0], map_dimensions, light_transparency_solid );
1311 cur_cache.seen_cache_dirty = false;
1312 }
1313
1314 if( z == target_z ) {
1315 seen_cache[origin.x][origin.y] = VISIBILITY_FULL;
1316 castLightAll<float, float, sight_calc, sight_check, update_light, accumulate_transparency>(
1317 seen_cache, transparency_cache, blocked_cache, origin.xy(), 0 );
1318 }
1319 }
1320 } else {
1321 // Cache the caches (pointers to them)
1322 array_of_grids_of<const float> transparency_caches;
1323 array_of_grids_of<float> seen_caches;
1324 array_of_grids_of<const bool> floor_caches;
1326 for( int z = -OVERMAP_DEPTH; z <= OVERMAP_HEIGHT; z++ ) {
1327 auto &cur_cache = get_cache( z );
1328 transparency_caches[z + OVERMAP_DEPTH] = &cur_cache.vision_transparency_cache;
1329 seen_caches[z + OVERMAP_DEPTH] = &cur_cache.seen_cache;
1330 floor_caches[z + OVERMAP_DEPTH] = &cur_cache.floor_cache;
1331 blocked_caches[z + OVERMAP_DEPTH] = &cur_cache.vehicle_obscured_cache;
1332 std::uninitialized_fill_n(
1333 &cur_cache.seen_cache[0][0], map_dimensions, light_transparency_solid );
1334 cur_cache.seen_cache_dirty = false;
1335 }
1336 if( origin.z == target_z ) {
1338 }
1340 seen_caches, transparency_caches, floor_caches, blocked_caches, origin, 0, 1.0 );
1341 }
1342
1344 if( !vp ) {
1345 return;
1346 }
1347 vehicle *const veh = &vp->vehicle();
1348
1349 // We're inside a vehicle. Do mirror calculations.
1350 std::vector<int> mirrors;
1351 // Do all the sight checks first to prevent fake multiple reflection
1352 // from happening due to mirrors becoming visible due to processing order.
1353 // Cameras are also handled here, so that we only need to get through all vehicle parts once
1354 int cam_control = -1;
1355 for( const vpart_reference &vp : veh->get_avail_parts( VPFLAG_EXTENDS_VISION ) ) {
1356 const tripoint mirror_pos = vp.pos();
1357 // We can utilize the current state of the seen cache to determine
1358 // if the player can see the mirror from their position.
1359 if( !vp.info().has_flag( "CAMERA" ) &&
1360 seen_cache[mirror_pos.x][mirror_pos.y] < LIGHT_TRANSPARENCY_SOLID + 0.1 ) {
1361 continue;
1362 } else if( !vp.info().has_flag( "CAMERA_CONTROL" ) ) {
1363 mirrors.emplace_back( static_cast<int>( vp.part_index() ) );
1364 } else {
1365 if( square_dist( origin, mirror_pos ) <= 1 && veh->camera_on ) {
1366 cam_control = static_cast<int>( vp.part_index() );
1367 }
1368 }
1369 }
1370
1371 for( int mirror : mirrors ) {
1372 bool is_camera = veh->part_info( mirror ).has_flag( "CAMERA" );
1373 if( is_camera && cam_control < 0 ) {
1374 continue; // Player not at camera control, so cameras don't work
1375 }
1376
1377 const tripoint mirror_pos = veh->global_part_pos3( mirror );
1378
1379 // Determine how far the light has already traveled so mirrors
1380 // don't cheat the light distance falloff.
1381 int offsetDistance;
1382 if( !is_camera ) {
1383 offsetDistance = rl_dist( origin, mirror_pos );
1384 } else {
1385 offsetDistance = 60 - veh->part_info( mirror ).bonus *
1386 veh->part( mirror ).hp() / veh->part_info( mirror ).durability;
1387 camera_cache[mirror_pos.x][mirror_pos.y] = LIGHT_TRANSPARENCY_OPEN_AIR;
1388 }
1389
1390 // TODO: Factor in the mirror facing and only cast in the
1391 // directions the player's line of sight reflects to.
1392 //
1393 // The naive solution of making the mirrors act like a second player
1394 // at an offset appears to give reasonable results though.
1395 castLightAll<float, float, sight_calc, sight_check, update_light, accumulate_transparency>(
1396 camera_cache, transparency_cache, blocked_cache, mirror_pos.xy(), offsetDistance );
1397 }
1398}
vehicle_part_with_feature_range< std::string > get_avail_parts(std::string feature) const
Yields a range of parts of this vehicle that each have the given feature and are available: not broke...
Definition: vehicle.cpp:2714
bool camera_on
Definition: vehicle.h:1996
const vpart_info & part_info(int index, bool include_removed=false) const
Definition: vehicle.cpp:1137
int bonus
seatbelt (str), muffler (%), horn (vol), light (intensity), recharing (power)
Definition: veh_type.h:269
bool has_flag(const std::string &flag) const
Definition: veh_type.h:336
int durability
Maximum damage part can sustain before being destroyed.
Definition: veh_type.h:173
template void cast_zlight< float, sight_calc, sight_check, accumulate_transparency >(const array_of_grids_of< float > &output_caches, const array_of_grids_of< const float > &input_arrays, const array_of_grids_of< const bool > &floor_caches, const array_of_grids_of< const diagonal_blocks > &blocked_caches, const tripoint &origin, int offset_distance, float numerator)
static constexpr float VISIBILITY_FULL
Definition: lightmap.h:39
std::array< T(*)[MAPSIZE_X][MAPSIZE_Y], OVERMAP_LAYERS > array_of_grids_of
int hp() const
current part health with range [0,durability]
@ VPFLAG_EXTENDS_VISION
Definition: veh_type.h:68

References vpart_info::bonus, vehicle::camera_on, cast_zlight< float, sight_calc, sight_check, accumulate_transparency >(), vpart_info::durability, fov_3d, vehicle::get_avail_parts(), get_cache(), vehicle::global_part_pos3(), vpart_info::has_flag(), vehicle_part::hp(), LIGHT_TRANSPARENCY_OPEN_AIR, LIGHT_TRANSPARENCY_SOLID, MAPSIZE_X, MAPSIZE_Y, OVERMAP_DEPTH, OVERMAP_HEIGHT, vehicle::part(), vehicle::part_info(), rl_dist(), level_cache::seen_cache, square_dist(), veh_at(), VISIBILITY_FULL, VPFLAG_EXTENDS_VISION, tripoint::x, tripoint::xy(), and tripoint::y.

Referenced by build_map_cache().

◆ build_sunlight_cache()

void map::build_sunlight_cache ( int  pzlev)
protected

Definition at line 220 of file lightmap.cpp.

221{
222 const int zlev_min = zlevels ? -OVERMAP_DEPTH : pzlev;
223 // Start at the topmost populated zlevel to avoid unnecessary raycasting
224 // Plus one zlevel to prevent clipping inside structures
225 const int zlev_max = zlevels
227 std::min( OVERMAP_HEIGHT, pzlev + 1 ),
229 : pzlev;
230
231 // true if all previous z-levels are fully transparent to light (no floors, transparency >= air)
232 bool fully_outside = true;
233
234 // true if no light reaches this level, i.e. there were no lit tiles on the above level (light level <= inside_light_level)
235 bool fully_inside = false;
236
237 // fully_outside and fully_inside define following states:
238 // initially: fully_outside=true, fully_inside=false (fast fill)
239 // ↓
240 // when first obstacles occur: fully_outside=false, fully_inside=false (slow quadrant logic)
241 // ↓
242 // when fully below ground: fully_outside=false, fully_inside=true (fast fill)
243
244 // Iterate top to bottom because sunlight cache needs to construct in that order.
245 for( int zlev = zlev_max; zlev >= zlev_min; zlev-- ) {
246
247 level_cache &map_cache = get_cache( zlev );
248 auto &lm = map_cache.lm;
249 // Grab illumination at ground level.
250 const float outside_light_level = g->natural_light_level( 0 );
251 // TODO: if zlev < 0 is open to sunlight, this won't calculate correct light, but neither does g->natural_light_level()
252 const float inside_light_level = ( zlev >= 0 && outside_light_level > LIGHT_SOURCE_BRIGHT ) ?
254 // Handling when z-levels are disabled is based on whether a tile is considered "outside".
255 if( !zlevels ) {
256 const auto &outside_cache = map_cache.outside_cache;
257 for( int x = 0; x < MAPSIZE_X; x++ ) {
258 for( int y = 0; y < MAPSIZE_Y; y++ ) {
259 if( outside_cache[x][y] ) {
260 lm[x][y].fill( outside_light_level );
261 } else {
262 lm[x][y].fill( inside_light_level );
263 }
264 }
265 }
266 continue;
267 }
268
269 // all light was blocked before
270 if( fully_inside ) {
271 std::fill_n( &lm[0][0], MAPSIZE_X * MAPSIZE_Y, four_quadrants( inside_light_level ) );
272 continue;
273 }
274
275 // If there were no obstacles before this level, just apply weather illumination since there's no opportunity
276 // for light to be blocked.
277 if( fully_outside ) {
278 //fill with full light
279 std::fill_n( &lm[0][0], MAPSIZE_X * MAPSIZE_Y, four_quadrants( outside_light_level ) );
280
281 const auto &this_floor_cache = map_cache.floor_cache;
282 const auto &this_transparency_cache = map_cache.transparency_cache;
283 fully_inside = true; // recalculate
284
285 for( int x = 0; x < MAPSIZE_X; ++x ) {
286 for( int y = 0; y < MAPSIZE_Y; ++y ) {
287 // && semantics below is important, we want to skip the evaluation if possible, do not replace with &=
288
289 // fully_outside stays true if tile is transparent and there is no floor
290 fully_outside = fully_outside && this_transparency_cache[x][y] >= LIGHT_TRANSPARENCY_OPEN_AIR
291 && !this_floor_cache[x][y];
292 // fully_inside stays true if tile is opaque OR there is floor
293 fully_inside = fully_inside && ( this_transparency_cache[x][y] <= LIGHT_TRANSPARENCY_SOLID ||
294 this_floor_cache[x][y] );
295 }
296 }
297 continue;
298 }
299
300 // Replace this with a calculated shift based on time of day and date.
301 // At first compress the angle such that it takes no more than one tile of shift per level.
302 // To exceed that, we'll have to handle casting light from the side instead of the top.
303 point offset;
304 const level_cache &prev_map_cache = get_cache_ref( zlev + 1 );
305 const auto &prev_lm = prev_map_cache.lm;
306 const auto &prev_transparency_cache = prev_map_cache.transparency_cache;
307 const auto &prev_floor_cache = prev_map_cache.floor_cache;
308 const auto &outside_cache = map_cache.outside_cache;
309 const float sight_penalty = get_weather().weather_id->sight_penalty;
310 // TODO: Replace these with a lookup inside the four_quadrants class.
311 constexpr std::array<point, 5> cardinals = {
313 };
314 constexpr std::array<std::array<quadrant, 2>, 5> dir_quadrants = {{
320 }
321 };
322
323 fully_inside = true; // recalculate
324
325 // Fall back to minimal light level if we don't find anything.
326 std::fill_n( &lm[0][0], MAPSIZE_X * MAPSIZE_Y, four_quadrants( inside_light_level ) );
327
328 for( int x = 0; x < MAPSIZE_X; ++x ) {
329 for( int y = 0; y < MAPSIZE_Y; ++y ) {
330 // Check center, then four adjacent cardinals.
331 for( int i = 0; i < 5; ++i ) {
332 int prev_x = x + offset.x + cardinals[i].x;
333 int prev_y = y + offset.y + cardinals[i].y;
334 bool inbounds = prev_x >= 0 && prev_x < MAPSIZE_X &&
335 prev_y >= 0 && prev_y < MAPSIZE_Y;
336
337 if( !inbounds ) {
338 continue;
339 }
340
341 float prev_light_max;
342 float prev_transparency = prev_transparency_cache[prev_x][prev_y];
343 // This is pretty gross, this cancels out the per-tile transparency effect
344 // derived from weather.
345 if( outside_cache[x][y] ) {
346 prev_transparency /= sight_penalty;
347 }
348
349 if( prev_transparency > LIGHT_TRANSPARENCY_SOLID &&
350 !prev_floor_cache[prev_x][prev_y] &&
351 ( prev_light_max = prev_lm[prev_x][prev_y].max() ) > 0.0 ) {
352 const float light_level = clamp( prev_light_max * LIGHT_TRANSPARENCY_OPEN_AIR / prev_transparency,
353 inside_light_level, prev_light_max );
354
355 if( i == 0 ) {
356 lm[x][y].fill( light_level );
357 fully_inside &= light_level <= inside_light_level;
358 break;
359 } else {
360 fully_inside &= light_level <= inside_light_level;
361 lm[x][y][dir_quadrants[i][0]] = light_level;
362 lm[x][y][dir_quadrants[i][1]] = light_level;
363 }
364 }
365 }
366 }
367 }
368 }
369}
constexpr T clamp(const T &val, const T &min, const T &max)
Clamp first argument so that it is no lower than second and no higher than third.
Definition: cata_utility.h:145
int calc_max_populated_zlev()
Caclulate the greatest populated zlevel in the loaded submaps and save in the level cache.
Definition: map.cpp:8923
weather_type_id weather_id
Definition: weather.h:193
weather_manager & get_weather()
Definition: weather.cpp:64
static constexpr float LIGHT_AMBIENT_DIM
Definition: lightmap.h:16
bool floor_cache[MAPSIZE_X][MAPSIZE_Y]
Definition: map.h:328
bool outside_cache[MAPSIZE_X][MAPSIZE_Y]
Definition: map.h:322
float sight_penalty
Definition: weather_type.h:111

References calc_max_populated_zlev(), clamp(), level_cache::floor_cache, g, get_cache(), get_cache_ref(), get_weather(), inbounds(), LIGHT_AMBIENT_DIM, LIGHT_AMBIENT_LOW, LIGHT_SOURCE_BRIGHT, LIGHT_TRANSPARENCY_OPEN_AIR, LIGHT_TRANSPARENCY_SOLID, level_cache::lm, MAPSIZE_X, MAPSIZE_Y, NE, NW, level_cache::outside_cache, OVERMAP_DEPTH, OVERMAP_HEIGHT, point_east, point_north, point_south, point_west, point_zero, SE, weather_type::sight_penalty, SW, level_cache::transparency_cache, weather_manager::weather_id, point::x, point::y, and zlevels.

Referenced by generate_lightmap().

◆ build_transparency_cache()

bool map::build_transparency_cache ( int  zlev)
protected

Definition at line 81 of file lightmap.cpp.

82{
83 auto &map_cache = get_cache( zlev );
84 auto &transparency_cache = map_cache.transparency_cache;
85 auto &outside_cache = map_cache.outside_cache;
86
87 if( map_cache.transparency_cache_dirty.none() ) {
88 return false;
89 }
90
91 std::set<tripoint> vehicles_processed;
92
93 // if true, all submaps are invalid (can use batch init)
94 bool rebuild_all = map_cache.transparency_cache_dirty.all();
95
96 if( rebuild_all ) {
97 // Default to just barely not transparent.
98 std::uninitialized_fill_n( &transparency_cache[0][0], MAPSIZE_X * MAPSIZE_Y,
99 static_cast<float>( LIGHT_TRANSPARENCY_OPEN_AIR ) );
100 }
101
102 const float sight_penalty = get_weather().weather_id->sight_penalty;
103
104 // Traverse the submaps in order
105 for( int smx = 0; smx < my_MAPSIZE; ++smx ) {
106 for( int smy = 0; smy < my_MAPSIZE; ++smy ) {
107 const auto cur_submap = get_submap_at_grid( {smx, smy, zlev} );
108
109 const point sm_offset = sm_to_ms_copy( point( smx, smy ) );
110
111 if( !rebuild_all && !map_cache.transparency_cache_dirty[smx * MAPSIZE + smy] ) {
112 continue;
113 }
114
115 // calculates transparency of a single tile
116 // x,y - coords in map local coords
117 auto calc_transp = [&]( const point & p ) {
118 const point sp = p - sm_offset;
119 float value = LIGHT_TRANSPARENCY_OPEN_AIR;
120
121 if( !( cur_submap->get_ter( sp ).obj().transparent &&
122 cur_submap->get_furn( sp ).obj().transparent ) ) {
124 }
125 if( outside_cache[p.x][p.y] ) {
126 // FIXME: Places inside vehicles haven't been marked as
127 // inside yet so this is incorrectly penalising for
128 // weather in vehicles.
129 value *= sight_penalty;
130 }
131 for( const auto &fld : cur_submap->get_field( sp ) ) {
132 const field_entry &cur = fld.second;
133 if( cur.is_transparent() ) {
134 continue;
135 }
136 // Fields are either transparent or not, however we want some to be translucent
137 value = value * cur.translucency();
138 }
139 // TODO: [lightmap] Have glass reduce light as well
140 return value;
141 };
142
143 if( cur_submap->is_uniform ) {
144 float value = calc_transp( sm_offset );
145 // if rebuild_all==true all values were already set to LIGHT_TRANSPARENCY_OPEN_AIR
146 if( !rebuild_all || value != LIGHT_TRANSPARENCY_OPEN_AIR ) {
147 for( int sx = 0; sx < SEEX; ++sx ) {
148 // init all sy indices in one go
149 std::uninitialized_fill_n( &transparency_cache[sm_offset.x + sx][sm_offset.y], SEEY, value );
150 }
151 }
152 } else {
153 for( int sx = 0; sx < SEEX; ++sx ) {
154 const int x = sx + sm_offset.x;
155 for( int sy = 0; sy < SEEY; ++sy ) {
156 const int y = sy + sm_offset.y;
157 transparency_cache[x][y] = calc_transp( { x, y } );
158 }
159 }
160 }
161 }
162 }
163 map_cache.transparency_cache_dirty.reset();
164 return true;
165}
An active or passive effect existing on a tile.
Definition: field.h:20
bool is_transparent() const
Definition: field.cpp:84
float translucency() const
Definition: field.cpp:79

References get_cache(), get_submap_at_grid(), get_weather(), field_entry::is_transparent(), LIGHT_TRANSPARENCY_OPEN_AIR, LIGHT_TRANSPARENCY_SOLID, MAPSIZE, MAPSIZE_X, MAPSIZE_Y, my_MAPSIZE, SEEX, SEEY, weather_type::sight_penalty, sm_to_ms_copy(), sx, sy, field_entry::translucency(), and weather_manager::weather_id.

Referenced by build_map_cache().

◆ build_vision_transparency_cache()

bool map::build_vision_transparency_cache ( int  zlev)
protected

Definition at line 167 of file lightmap.cpp.

168{
169 auto &map_cache = get_cache( zlev );
170 auto &transparency_cache = map_cache.transparency_cache;
171 auto &vision_transparency_cache = map_cache.vision_transparency_cache;
172
173 memcpy( &vision_transparency_cache, &transparency_cache, sizeof( transparency_cache ) );
174
175 const tripoint &p = g->u.pos();
176
177 if( p.z != zlev ) {
178 return false;
179 }
180
181 bool dirty = false;
182
183 bool is_crouching = g->u.movement_mode_is( CMM_CROUCH );
184 for( const tripoint &loc : points_in_radius( p, 1 ) ) {
185 if( loc == p ) {
186 // The tile player is standing on should always be visible
187 vision_transparency_cache[p.x][p.y] = LIGHT_TRANSPARENCY_OPEN_AIR;
188 } else if( is_crouching && coverage( loc ) >= 30 ) {
189 // If we're crouching behind an obstacle, we can't see past it.
190 vision_transparency_cache[loc.x][loc.y] = LIGHT_TRANSPARENCY_SOLID;
191 dirty = true;
192 }
193 }
194
195 return dirty;
196}
@ CMM_CROUCH
Definition: character.h:104
int coverage(const tripoint &p) const
Returns coverage value of the tile.
Definition: map.cpp:6244

References CMM_CROUCH, coverage(), g, get_cache(), LIGHT_TRANSPARENCY_OPEN_AIR, LIGHT_TRANSPARENCY_SOLID, points_in_radius(), tripoint::x, tripoint::y, and tripoint::z.

Referenced by build_map_cache().

◆ burn_body_part()

int map::burn_body_part ( player u,
field_entry cur,
body_part  bp,
int  scale 
)
private

Definition at line 124 of file map_field.cpp.

125{
126 int total_damage = 0;
127 const int intensity = cur.get_field_intensity();
128 const int damage = rng( 1, ( scale + intensity ) / 2 );
129 // A bit ugly, but better than being annoyed by acid when in hazmat
130 if( u.get_armor_type( DT_ACID, convert_bp( bp ) ) < damage ) {
131 const dealt_damage_instance ddi = u.deal_damage( nullptr, convert_bp( bp ).id(),
132 damage_instance( DT_ACID, damage ) );
133 total_damage += ddi.total_damage();
134 }
135 // Represents acid seeping in rather than being splashed on
137 1 + intensity ) ), bp, 0 );
138 return total_damage;
139}
units::quantity< V, B > rng(const units::quantity< V, B > &min, const units::quantity< V, B > &max)
Definition: artifact.cpp:32
const bodypart_str_id & convert_bp(body_part bp)
Returns the new id for old token.
Definition: bodypart.cpp:185
dealt_damage_instance deal_damage(Creature *source, bodypart_id bp, const damage_instance &d) override
Calls Creature::deal_damage and handles damaged effects (waking up, etc.)
Definition: character.cpp:8468
int get_armor_type(damage_type dt, bodypart_id bp) const override
Returns overall resistance to given type on the bod part.
Definition: character.cpp:6987
bool add_env_effect(const efftype_id &eff_id, body_part vector, int strength, const time_duration &dur, body_part bp=num_bp, int intensity=1, bool force=false)
Gives chance to save via environmental resist, returns false if resistance was successful.
Definition: creature.cpp:1112
int get_field_intensity() const
Definition: field.cpp:121
static constexpr time_duration from_turns(const T t)
Named constructors to get a duration representing a multiple of the named time units.
Definition: calendar.h:204
@ DT_ACID
Definition: damage.h:26
static const efftype_id effect_corroding("corroding")
int total_damage() const
Definition: damage.cpp:180

References Creature::add_env_effect(), convert_bp(), Character::deal_damage(), DT_ACID, effect_corroding, time_duration::from_turns(), Character::get_armor_type(), field_entry::get_field_intensity(), rng(), and dealt_damage_instance::total_damage().

Referenced by player_in_field().

◆ calc_max_populated_zlev()

int map::calc_max_populated_zlev ( )
private

Caclulate the greatest populated zlevel in the loaded submaps and save in the level cache.

fills the map::max_populated_zlev and returns it

Returns
max_populated_zlev value

Definition at line 8923 of file map.cpp.

8924{
8925 // cache is filled and valid, skip recalculation
8927 return max_populated_zlev->second;
8928 }
8929
8930 // We'll assume ground level is populated
8931 int max_z = 0;
8932
8933 for( int sz = 1; sz <= OVERMAP_HEIGHT; sz++ ) {
8934 bool level_done = false;
8935 for( int sx = 0; sx < my_MAPSIZE; sx++ ) {
8936 for( int sy = 0; sy < my_MAPSIZE; sy++ ) {
8937 const submap *sm = get_submap_at_grid( tripoint( sx, sy, sz ) );
8938 if( !sm->is_uniform ) {
8939 max_z = sz;
8940 level_done = true;
8941 break;
8942 }
8943 }
8944 if( level_done ) {
8945 break;
8946 }
8947 }
8948 }
8949
8950 max_populated_zlev = std::pair<tripoint, int>( get_abs_sub(), max_z );
8951 return max_z;
8952}
cata::optional< std::pair< tripoint, int > > max_populated_zlev
Definition: map.h:2037
tripoint get_abs_sub() const
return abs_sub
Definition: map.cpp:8276

References get_abs_sub(), get_submap_at_grid(), max_populated_zlev, my_MAPSIZE, OVERMAP_HEIGHT, coords::sm, sx, and sy.

Referenced by build_sunlight_cache().

◆ can_move_furniture()

bool map::can_move_furniture ( const tripoint pos,
player p = nullptr 
)
Strength determines what furniture the player can move

Definition at line 1445 of file map.cpp.

1446{
1447 if( !p ) {
1448 return false;
1449 }
1450 const furn_t &furniture_type = furn( pos ).obj();
1451 int required_str = furniture_type.move_str_req;
1452
1453 // Object can not be moved (or nothing there)
1454 if( required_str < 0 ) {
1455 return false;
1456 }
1457
1458 ///\EFFECT_STR determines what furniture the player can move
1459 int adjusted_str = p->str_cur;
1460 if( p->is_mounted() ) {
1461 auto mons = p->mounted_creature.get();
1462 if( mons->has_flag( MF_RIDEABLE_MECH ) && mons->mech_str_addition() != 0 ) {
1463 adjusted_str = mons->mech_str_addition();
1464 }
1465 }
1466 return adjusted_str >= required_str;
1467}
int str_cur
Definition: character.h:247
bool is_mounted() const
Definition: character.cpp:1143
shared_ptr_fast< monster > mounted_creature
Definition: character.h:1556
@ MF_RIDEABLE_MECH
Definition: mtype.h:115
int move_str_req
Definition: mapdata.h:511

References furn(), Character::is_mounted(), MF_RIDEABLE_MECH, Character::mounted_creature, furn_t::move_str_req, int_id< T >::obj(), wrapped_vehicle::pos, and Character::str_cur.

Referenced by grab().

◆ can_put_items() [1/2]

bool map::can_put_items ( const point p) const
inline

Definition at line 974 of file map.h.

974 {
975 return can_put_items( tripoint( p, abs_sub.z ) );
976 }
bool can_put_items(const tripoint &p) const
Definition: map.cpp:2298

References abs_sub, can_put_items(), and tripoint::z.

◆ can_put_items() [2/2]

bool map::can_put_items ( const tripoint p) const

Definition at line 2298 of file map.cpp.

2299{
2300 if( can_put_items_ter_furn( p ) ) {
2301 return true;
2302 }
2303 const optional_vpart_position vp = veh_at( p );
2304 return static_cast<bool>( vp.part_with_feature( "CARGO", true ) );
2305}
bool can_put_items_ter_furn(const tripoint &p) const
Definition: map.cpp:2307

References can_put_items_ter_furn(), optional_vpart_position::part_with_feature(), and veh_at().

Referenced by can_put_items(), complete_construction(), haul(), and game::place_player().

◆ can_put_items_ter_furn() [1/2]

bool map::can_put_items_ter_furn ( const point p) const
inline

Definition at line 979 of file map.h.

979 {
981 }

References abs_sub, can_put_items_ter_furn(), and tripoint::z.

◆ can_put_items_ter_furn() [2/2]

bool map::can_put_items_ter_furn ( const tripoint p) const

◆ can_see_trap_at()

bool map::can_see_trap_at ( const tripoint p,
const Character c 
) const

See trap::can_see, which is called for the trap here.

Definition at line 5120 of file map.cpp.

5121{
5122 return tr_at( p ).can_see( p, c );
5123}
const trap & tr_at(const tripoint &p) const
Definition: map.cpp:5125
constexpr double c
Definition: magic.cpp:1032
bool can_see(const tripoint &pos, const Character &p) const
Can player/npc p see this kind of trap, either by their memory (they known there is the trap) or by t...
Definition: trap.cpp:223

References c, trap::can_see(), and tr_at().

Referenced by can_examine_at(), and vehicle::autodrive_controller::check_drivable().

◆ check_and_set_seen_cache()

bool map::check_and_set_seen_cache ( const tripoint p) const
inline

Definition at line 491 of file map.h.

491 {
492 std::bitset<MAPSIZE_X *MAPSIZE_Y> &memory_seen_cache =
494 if( !memory_seen_cache[ static_cast<size_t>( p.x + p.y * MAPSIZE_Y ) ] ) {
495 memory_seen_cache.set( static_cast<size_t>( p.x + p.y * MAPSIZE_Y ) );
496 return true;
497 }
498 return false;
499 }
std::bitset< MAPSIZE_X *MAPSIZE_Y > map_memory_seen_cache
Definition: map.h:356

References get_cache(), level_cache::map_memory_seen_cache, MAPSIZE_Y, tripoint::x, tripoint::y, and tripoint::z.

Referenced by draw_maptile().

◆ check_seen_cache()

bool map::check_seen_cache ( const tripoint p) const
inline

Definition at line 486 of file map.h.

486 {
487 std::bitset<MAPSIZE_X *MAPSIZE_Y> &memory_seen_cache =
489 return !memory_seen_cache[ static_cast<size_t>( p.x + p.y * MAPSIZE_Y ) ];
490 }

References get_cache(), level_cache::map_memory_seen_cache, MAPSIZE_Y, tripoint::x, tripoint::y, and tripoint::z.

◆ check_submap_active_item_consistency()

std::vector< tripoint > map::check_submap_active_item_consistency ( )

Definition at line 4543 of file map.cpp.

4544{
4545 std::vector<tripoint> result;
4546 for( int z = -OVERMAP_DEPTH; z < OVERMAP_HEIGHT; ++z ) {
4547 for( int x = 0; x < MAPSIZE; ++x ) {
4548 for( int y = 0; y < MAPSIZE; ++y ) {
4549 tripoint p( x, y, z );
4550 submap *s = get_submap_at_grid( p );
4551 bool has_active_items = !s->active_items.get().empty();
4552 bool map_has_active_items = submaps_with_active_items.count( p + abs_sub.xy() );
4553 if( has_active_items != map_has_active_items ) {
4554 result.push_back( p + abs_sub.xy() );
4555 }
4556 }
4557 }
4558 }
4559 for( const tripoint &p : submaps_with_active_items ) {
4560 tripoint rel = p - abs_sub.xy();
4562 if( !map.contains( rel.xy() ) ) {
4563 result.push_back( p );
4564 }
4565 }
4566 return result;
4567}
std::vector< item_reference > get()
Returns a vector of all cached active item references.
Manage and cache data about a part of the map.
Definition: map.h:389

References abs_sub, submap::active_items, active_item_cache::get(), get_submap_at_grid(), map(), MAPSIZE, OVERMAP_DEPTH, OVERMAP_HEIGHT, point_zero, submaps_with_active_items, and tripoint::xy().

◆ check_vehicle_zones()

bool map::check_vehicle_zones ( int  zlev)

Definition at line 929 of file map.cpp.

930{
931 for( auto veh : get_cache( zlev ).zone_vehicles ) {
932 if( veh->zones_dirty ) {
933 return true;
934 }
935 }
936 return false;
937}

References get_cache().

Referenced by activity_on_turn_move_loot(), talk_function::basecamp_mission(), basecamp::distribute_food(), find_auto_consume(), basecamp::place_results(), and basecamp::validate_sort_points().

◆ clear_path()

bool map::clear_path ( const tripoint f,
const tripoint t,
int  range,
int  cost_min,
int  cost_max 
) const

Check whether there's a direct line of sight between F and T with the additional movecost restraints.

Checks two things:

  1. The sees() algorithm between F and T
  2. That moving over the line of sight would have a move_cost between cost_min and cost_max.

Definition at line 6394 of file map.cpp.

6396{
6397 // Ugly `if` for now
6398 if( !fov_3d && f.z != t.z ) {
6399 return false;
6400 }
6401
6402 if( f.z == t.z ) {
6403 if( ( range >= 0 && range < rl_dist( f.xy(), t.xy() ) ) ||
6404 !inbounds( t ) ) {
6405 return false; // Out of range!
6406 }
6407 bool is_clear = true;
6408 point last_point = f.xy();
6409 bresenham( f.xy(), t.xy(), 0,
6410 [this, &is_clear, cost_min, cost_max, &t, &last_point]( const point & new_point ) {
6411 // Exit before checking the last square, it's still reachable even if it is an obstacle.
6412 if( new_point.x == t.x && new_point.y == t.y ) {
6413 return false;
6414 }
6415
6416 const int cost = this->move_cost( new_point );
6417 if( cost < cost_min || cost > cost_max ||
6418 obstructed_by_vehicle_rotation( tripoint( last_point, t.z ), tripoint( new_point,
6419 t.z ) ) ) {
6420 is_clear = false;
6421 return false;
6422 }
6423
6424 last_point = new_point;
6425 return true;
6426 } );
6427 return is_clear;
6428 }
6429
6430 if( ( range >= 0 && range < rl_dist( f, t ) ) ||
6431 !inbounds( t ) ) {
6432 return false; // Out of range!
6433 }
6434 bool is_clear = true;
6435 tripoint last_point = f;
6436 bresenham( f, t, 0, 0,
6437 [this, &is_clear, cost_min, cost_max, t, &last_point]( const tripoint & new_point ) {
6438 // Exit before checking the last square, it's still reachable even if it is an obstacle.
6439 if( new_point == t ) {
6440 return false;
6441 }
6442
6443 // We have to check a weird case where the move is both vertical and horizontal
6444 if( new_point.z == last_point.z ) {
6445 const int cost = move_cost( new_point );
6446 if( cost < cost_min || cost > cost_max ||
6447 obstructed_by_vehicle_rotation( last_point, new_point ) ) {
6448 is_clear = false;
6449 return false;
6450 }
6451 } else {
6452 bool this_clear = false;
6453 const int max_z = std::max( new_point.z, last_point.z );
6454 if( !has_floor_or_support( {new_point.xy(), max_z} ) ) {
6455 const int cost = move_cost( {new_point.xy(), last_point.z} );
6456 if( cost > cost_min && cost < cost_max &&
6457 !obstructed_by_vehicle_rotation( last_point, new_point ) ) {
6458 this_clear = true;
6459 }
6460 }
6461
6462 if( !this_clear && has_floor_or_support( {last_point.xy(), max_z} ) ) {
6463 const int cost = move_cost( {last_point.xy(), new_point.z} );
6464 if( cost > cost_min && cost < cost_max &&
6465 !obstructed_by_vehicle_rotation( last_point, new_point ) ) {
6466 this_clear = true;
6467 }
6468 }
6469
6470 if( !this_clear ) {
6471 is_clear = false;
6472 return false;
6473 }
6474 }
6475
6476 last_point = new_point;
6477 return true;
6478 } );
6479 return is_clear;
6480}
bool has_floor_or_support(const tripoint &p) const
Definition: map.cpp:2039
int move_cost(const tripoint &p, const vehicle *ignored_vehicle=nullptr) const
Calculate the cost to move past the tile at p.
Definition: map.cpp:1780
void bresenham(const point &p1, const point &p2, int t, const std::function< bool(const point &)> &interact)
The actual Bresenham algorithm in 2D and 3D, everything else should call these and pass in an interac...
Definition: line.cpp:24

References bresenham(), fov_3d, inbounds(), obstructed_by_vehicle_rotation(), rl_dist(), tripoint::xy(), and tripoint::z.

Referenced by find_best_fire(), player::get_eligible_containers_for_crafting(), has_clear_path_to_pickup_items(), points_for_gas_cloud(), process_fields_in_submap(), mattack::riotbot(), game::start_game(), and vehicle_selector::vehicle_selector().

◆ clear_spawns()

void map::clear_spawns ( )

Definition at line 7722 of file map.cpp.

7723{
7724 for( auto &smap : grid ) {
7725 smap->spawns.clear();
7726 }
7727}

References grid.

Referenced by defense_game::init_map().

◆ clear_traps()

void map::clear_traps ( )

Definition at line 7729 of file map.cpp.

7730{
7731 for( auto &smap : grid ) {
7732 for( int x = 0; x < SEEX; x++ ) {
7733 for( int y = 0; y < SEEY; y++ ) {
7734 const point p( x, y );
7735 smap->set_trap( p, tr_null );
7736 }
7737 }
7738 }
7739
7740 // Forget about all trap locations.
7741 for( auto &i : traplocs ) {
7742 i.clear();
7743 }
7744}

References grid, SEEX, SEEY, tr_null, and traplocs.

Referenced by defense_game::init_map().

◆ clear_vehicle_cache()

void map::clear_vehicle_cache ( )

Definition at line 313 of file map.cpp.

314{
315 const int zmin = zlevels ? -OVERMAP_DEPTH : abs_sub.z;
316 const int zmax = zlevels ? OVERMAP_HEIGHT : abs_sub.z;
317 for( int zlev = zmin; zlev <= zmax; zlev++ ) {
318 level_cache &ch = get_cache( zlev );
319 while( !ch.veh_cached_parts.empty() ) {
320 const auto part = ch.veh_cached_parts.begin();
321 const auto &p = part->first;
322 if( inbounds( p ) ) {
323 ch.veh_exists_at[p.x][p.y] = false;
324 }
325 ch.veh_cached_parts.erase( part );
326 }
327 ch.veh_in_active_range = false;
328 }
329}

References abs_sub, get_cache(), inbounds(), OVERMAP_DEPTH, OVERMAP_HEIGHT, level_cache::veh_cached_parts, level_cache::veh_exists_at, level_cache::veh_in_active_range, tripoint::z, and zlevels.

Referenced by editmap::mapgen_preview(), game::place_player_overmap(), reset_vehicle_cache(), rotate(), shift(), and game::vertical_shift().

◆ clear_vehicle_list()

void map::clear_vehicle_list ( int  zlev)

Definition at line 331 of file map.cpp.

332{
333 auto &ch = get_cache( zlev );
334 ch.vehicle_list.clear();
335 ch.zone_vehicles.clear();
336
338}

References get_cache(), and last_full_vehicle_list_dirty.

Referenced by editmap::mapgen_preview(), editmap::mapgen_veh_destroy(), game::place_player_overmap(), rotate(), and shift().

◆ clear_vehicle_point_from_cache()

void map::clear_vehicle_point_from_cache ( vehicle veh,
const tripoint pt 
)

Definition at line 295 of file map.cpp.

296{
297 if( veh == nullptr ) {
298 debugmsg( "Tried to clear null vehicle from cache" );
299 return;
300 }
301
302 level_cache &ch = get_cache( pt.z );
303 if( inbounds( pt ) ) {
304 ch.veh_exists_at[pt.x][pt.y] = false;
305 }
306 auto it = ch.veh_cached_parts.find( pt );
307 if( it != ch.veh_cached_parts.end() && it->second.first == veh ) {
308 ch.veh_cached_parts.erase( it );
309 }
310
311}

References debugmsg, get_cache(), inbounds(), level_cache::veh_cached_parts, level_cache::veh_exists_at, tripoint::x, tripoint::y, and tripoint::z.

Referenced by vehicle::advance_precalc_mounts(), veh_interact::complete_vehicle(), and vehicle::part_removal_cleanup().

◆ climb_difficulty()

int map::climb_difficulty ( const tripoint p) const

Checks 3x3 block centered on p for terrain to climb.

Returns
Difficulty of climbing check from point p.

Definition at line 1969 of file map.cpp.

1970{
1971 if( p.z > OVERMAP_HEIGHT || p.z < -OVERMAP_DEPTH ) {
1972 debugmsg( "climb_difficulty on out of bounds point: %d, %d, %d", p.x, p.y, p.z );
1973 return INT_MAX;
1974 }
1975
1976 int best_difficulty = INT_MAX;
1977 int blocks_movement = 0;
1978 if( has_flag( "LADDER", p ) ) {
1979 // Really easy, but you have to stand on the tile
1980 return 1;
1981 } else if( has_flag( TFLAG_RAMP, p ) || has_flag( TFLAG_RAMP_UP, p ) ||
1982 has_flag( TFLAG_RAMP_DOWN, p ) ) {
1983 // We're on something stair-like, so halfway there already
1984 best_difficulty = 7;
1985 }
1986
1987 for( const auto &pt : points_in_radius( p, 1 ) ) {
1988 if( impassable_ter_furn( pt ) ) {
1989 // TODO: Non-hardcoded climbability
1990 best_difficulty = std::min( best_difficulty, 10 );
1991 blocks_movement++;
1992 } else if( veh_at( pt ) ) {
1993 // Vehicle tiles are quite good for climbing
1994 // TODO: Penalize spiked parts?
1995 best_difficulty = std::min( best_difficulty, 7 );
1996 }
1997
1998 if( best_difficulty > 5 && has_flag( "CLIMBABLE", pt ) ) {
1999 best_difficulty = 5;
2000 }
2001 }
2002
2003 // TODO: Make this more sensible - check opposite sides, not just movement blocker count
2004 return best_difficulty - blocks_movement;
2005}
bool impassable_ter_furn(const tripoint &p) const
Definition: map.cpp:1828
@ TFLAG_RAMP_UP
Definition: mapdata.h:313
@ TFLAG_RAMP
Definition: mapdata.h:314
@ TFLAG_RAMP_DOWN
Definition: mapdata.h:312

References debugmsg, has_flag(), impassable_ter_furn(), OVERMAP_DEPTH, OVERMAP_HEIGHT, points_in_radius(), TFLAG_RAMP, TFLAG_RAMP_DOWN, TFLAG_RAMP_UP, veh_at(), tripoint::x, tripoint::y, and tripoint::z.

Referenced by map_funcs::climbing_cost().

◆ clip_to_bounds() [1/3]

void map::clip_to_bounds ( int &  x,
int &  y 
) const

Definition at line 8866 of file map.cpp.

8867{
8868 if( x < 0 ) {
8869 x = 0;
8870 } else if( x >= SEEX * my_MAPSIZE ) {
8871 x = SEEX * my_MAPSIZE - 1;
8872 }
8873
8874 if( y < 0 ) {
8875 y = 0;
8876 } else if( y >= SEEY * my_MAPSIZE ) {
8877 y = SEEY * my_MAPSIZE - 1;
8878 }
8879}

References my_MAPSIZE, SEEX, and SEEY.

◆ clip_to_bounds() [2/3]

void map::clip_to_bounds ( int &  x,
int &  y,
int &  z 
) const

Definition at line 8881 of file map.cpp.

8882{
8883 clip_to_bounds( x, y );
8884 if( z < -OVERMAP_DEPTH ) {
8885 z = -OVERMAP_DEPTH;
8886 } else if( z > OVERMAP_HEIGHT ) {
8887 z = OVERMAP_HEIGHT;
8888 }
8889}
void clip_to_bounds(tripoint &p) const
Clips the coordinates of p to fit the map bounds.
Definition: map.cpp:8861

References clip_to_bounds(), OVERMAP_DEPTH, and OVERMAP_HEIGHT.

◆ clip_to_bounds() [3/3]

void map::clip_to_bounds ( tripoint p) const

Clips the coordinates of p to fit the map bounds.

Definition at line 8861 of file map.cpp.

8862{
8863 clip_to_bounds( p.x, p.y, p.z );
8864}

References clip_to_bounds(), tripoint::x, tripoint::y, and tripoint::z.

Referenced by MapgenRemovePartHandler::add_item_or_charges(), clip_to_bounds(), and route().

◆ close_door()

bool map::close_door ( const tripoint p,
bool  inside,
bool  check_only 
)

Definition at line 3963 of file map.cpp.

3964{
3965 if( has_flag( "OPENCLOSE_INSIDE", p ) && !inside ) {
3966 return false;
3967 }
3968
3969 const auto &ter = this->ter( p ).obj();
3970 const auto &furn = this->furn( p ).obj();
3971 if( ter.close && !furn.id ) {
3972 if( !check_only ) {
3973 sounds::sound( p, 10, sounds::sound_t::movement, _( "swish" ), true,
3974 "close_door", ter.id.str() );
3975 ter_set( p, ter.close );
3976 }
3977 return true;
3978 } else if( furn.close ) {
3979 if( !check_only ) {
3980 sounds::sound( p, 10, sounds::sound_t::movement, _( "swish" ), true,
3981 "close_door", furn.id.str() );
3982 furn_set( p, furn.close );
3983 }
3984 return true;
3985 }
3986 return false;
3987}
const string_id< T > & id() const
Definition: ammo_effect.cpp:33

References _, furn(), furn_set(), has_flag(), int_id< T >::id(), sounds::movement, int_id< T >::obj(), sounds::sound(), string_id< T >::str(), ter(), and ter_set().

Referenced by can_interact_at(), doors::close_door(), and game::try_get_right_click_action().

◆ collapse_at()

void map::collapse_at ( const tripoint p,
bool  silent,
bool  was_supporting = false,
bool  destroy_pos = true 
)

Causes a collapse at p, such as from destroying a wall.

Definition at line 2898 of file map.cpp.

2900{
2901 const bool supports = was_supporting || has_flag( TFLAG_SUPPORTS_ROOF, p );
2902 const bool wall = was_supporting || has_flag( TFLAG_WALL, p );
2903 // don't bash again if the caller already bashed here
2904 if( destroy_pos ) {
2905 destroy( p, silent );
2906 crush( p );
2907 make_rubble( p );
2908 }
2909 const bool still_supports = has_flag( TFLAG_SUPPORTS_ROOF, p );
2910
2911 // If something supporting the roof collapsed, see what else collapses
2912 if( supports && !still_supports ) {
2913 for( const tripoint &t : points_in_radius( p, 1 ) ) {
2914 // If z-levels are off, tz == t, so we end up skipping a lot of stuff to avoid bugs.
2915 const tripoint &tz = tripoint( t.xy(), t.z + 1 );
2916 // if nothing above us had the chance of collapsing, move on
2917 if( !one_in( collapse_check( tz ) ) ) {
2918 continue;
2919 }
2920 // if a wall collapses, walls without support from below risk collapsing and
2921 //propagate the collapse upwards
2922 if( zlevels && wall && p == t && has_flag( TFLAG_WALL, tz ) ) {
2923 collapse_at( tz, silent );
2924 }
2925 // floors without support from below risk collapsing into open air and can propagate
2926 // the collapse horizontally but not vertically
2927 if( p != t && ( has_flag( TFLAG_SUPPORTS_ROOF, t ) && has_flag( TFLAG_COLLAPSES, t ) ) ) {
2928 collapse_at( t, silent );
2929 }
2930 // this tile used to support a roof, now it doesn't, which means there is only
2931 // open air above us
2932 if( zlevels ) {
2933 ter_set( tz, t_open_air );
2934 furn_set( tz, f_null );
2936 }
2937 }
2938 }
2939 // it would be great to check if collapsing ceilings smashed through the floor, but
2940 // that's not handled for now
2941}
void crush(const tripoint &p)
Definition: map.cpp:3661
int collapse_check(const tripoint &p)
Checks if a square should collapse, returns the X for the one_in(X) collapse chance.
Definition: map.cpp:2849
void make_rubble(const tripoint &p, const furn_id &rubble_type, bool items, const ter_id &floor_type, bool overwrite=false)
Generates rubble at the given location, if overwrite is true it just writes on top of what currently ...
Definition: map.cpp:2498
@ TFLAG_COLLAPSES
Definition: mapdata.h:288
@ TFLAG_WALL
Definition: mapdata.h:300

References collapse_at(), collapse_check(), crush(), destroy(), f_null, furn_set(), has_flag(), make_rubble(), one_in(), points_in_radius(), propagate_suspension_check(), silent, t_open_air, ter_set(), TFLAG_COLLAPSES, TFLAG_SUPPORTS_ROOF, TFLAG_WALL, and zlevels.

Referenced by bash_ter_success(), collapse_at(), and talk_function::loot_building().

◆ collapse_check()

int map::collapse_check ( const tripoint p)

Checks if a square should collapse, returns the X for the one_in(X) collapse chance.

Definition at line 2849 of file map.cpp.

2850{
2851 const bool collapses = has_flag( TFLAG_COLLAPSES, p );
2852 const bool supports_roof = has_flag( TFLAG_SUPPORTS_ROOF, p );
2853
2854 int num_supports = p.z == -OVERMAP_DEPTH ? 0 : -5;
2855 // if there's support below, things are less likely to collapse
2856 if( p.z > -OVERMAP_DEPTH ) {
2857 const tripoint &pbelow = tripoint( p.xy(), p.z - 1 );
2858 for( const tripoint &tbelow : points_in_radius( pbelow, 1 ) ) {
2859 if( has_flag( TFLAG_SUPPORTS_ROOF, pbelow ) ) {
2860 num_supports += 1;
2861 if( has_flag( TFLAG_WALL, pbelow ) ) {
2862 num_supports += 2;
2863 }
2864 if( tbelow == pbelow ) {
2865 num_supports += 2;
2866 }
2867 }
2868 }
2869 }
2870
2871 for( const tripoint &t : points_in_radius( p, 1 ) ) {
2872 if( p == t ) {
2873 continue;
2874 }
2875
2876 if( collapses ) {
2877 if( has_flag( TFLAG_COLLAPSES, t ) ) {
2878 num_supports++;
2879 } else if( has_flag( TFLAG_SUPPORTS_ROOF, t ) ) {
2880 num_supports += 2;
2881 }
2882 } else if( supports_roof ) {
2883 if( has_flag( TFLAG_SUPPORTS_ROOF, t ) ) {
2884 if( has_flag( TFLAG_WALL, t ) ) {
2885 num_supports += 4;
2886 } else if( !has_flag( TFLAG_COLLAPSES, t ) ) {
2887 num_supports += 3;
2888 }
2889 }
2890 }
2891 }
2892
2893 return 1.7 * num_supports;
2894}

References has_flag(), OVERMAP_DEPTH, points_in_radius(), TFLAG_COLLAPSES, TFLAG_SUPPORTS_ROOF, TFLAG_WALL, tripoint::xy(), and tripoint::z.

Referenced by collapse_at().

◆ collapse_invalid_suspension()

void map::collapse_invalid_suspension ( const tripoint point)

Triggers a recursive collapse of suspended tiles based on their support validity.

Definition at line 2952 of file map.cpp.

2953{
2954 if( !is_suspension_valid( point ) ) {
2956 furn_set( point, f_null );
2957
2959 }
2960}
bool is_suspension_valid(const tripoint &point)
Checks the four orientations in which a suspended tile could be valid, and returns if the tile is val...
Definition: map.cpp:2962

References f_null, furn_set(), is_suspension_valid(), propagate_suspension_check(), t_open_air, and ter_set().

Referenced by drop_everything(), and propagate_suspension_check().

◆ combined_movecost()

int map::combined_movecost ( const tripoint from,
const tripoint to,
const vehicle ignored_vehicle = nullptr,
int  modifier = 0,
bool  flying = false,
bool  via_ramp = false 
) const

Cost to move out of one tile and into the next.

Returns
The cost in turns to move out of tripoint from and into to

Definition at line 1838 of file map.cpp.

1841{
1842 const int mults[4] = { 0, 50, 71, 100 };
1843 const int cost1 = move_cost( from, ignored_vehicle );
1844 const int cost2 = move_cost( to, ignored_vehicle );
1845 // Multiply cost depending on the number of differing axes
1846 // 0 if all axes are equal, 100% if only 1 differs, 141% for 2, 200% for 3
1847 size_t match = trigdist ? ( from.x != to.x ) + ( from.y != to.y ) + ( from.z != to.z ) : 1;
1848 if( flying || from.z == to.z ) {
1849 return ( cost1 + cost2 + modifier ) * mults[match] / 2;
1850 }
1851
1852 // Inter-z-level movement by foot (not flying)
1853 if( !valid_move( from, to, false, via_ramp ) ) {
1854 return 0;
1855 }
1856
1857 // TODO: Penalize for using stairs
1858 return ( cost1 + cost2 + modifier ) * mults[match] / 2;
1859}
bool valid_move(const tripoint &from, const tripoint &to, bool bash=false, bool flying=false, bool via_ramp=false) const
Returns true if a creature could walk from from to to in one step.
Definition: map.cpp:1861

References move_cost(), trigdist, valid_move(), tripoint::x, tripoint::y, and tripoint::z.

Referenced by npc::move_away_from(), npc::move_to(), and game::walk_move().

◆ computer_at()

computer * map::computer_at ( const tripoint p)

Definition at line 5542 of file map.cpp.

5543{
5544 if( !inbounds( p ) ) {
5545 return nullptr;
5546 }
5547
5548 point l;
5549 submap *const sm = get_submap_at( p, l );
5550 return sm->get_computer( l );
5551}

References get_submap_at(), inbounds(), and coords::sm.

Referenced by mission_start::reveal_lab_train_depot(), and game::use_computer().

◆ copy_grid()

void map::copy_grid ( const tripoint to,
const tripoint from 
)
protected

Definition at line 7507 of file map.cpp.

7508{
7509 const auto smap = get_submap_at_grid( from );
7510 setsubmap( get_nonant( to ), smap );
7511 for( auto &it : smap->vehicles ) {
7512 it->sm_pos = to;
7513 }
7514}
void setsubmap(size_t grididx, submap *smap)
Set the submap pointer in grid at the give index.
Definition: map.cpp:8290
size_t get_nonant(const tripoint &gridp) const
Get the index of a submap pointer in the grid given by grid coordinates.
Definition: map.cpp:8323

References get_nonant(), get_submap_at_grid(), and setsubmap().

Referenced by shift().

◆ could_see_items() [1/2]

bool map::could_see_items ( const tripoint p,
const Creature who 
) const

Check if the creature could see items at p if there were any items.

This is similar to sees_some_items, but it does not check that there are actually any items.

Definition at line 4736 of file map.cpp.

4737{
4738 return could_see_items( p, who.pos() );
4739}
virtual const tripoint & pos() const =0
bool could_see_items(const tripoint &p, const Creature &who) const
Check if the creature could see items at p if there were any items.
Definition: map.cpp:4736

References could_see_items(), and Creature::pos().

Referenced by could_see_items(), game::print_items_info(), and sees_some_items().

◆ could_see_items() [2/2]

bool map::could_see_items ( const tripoint p,
const tripoint from 
) const

Definition at line 4741 of file map.cpp.

4742{
4743 static const std::string container_string( "CONTAINER" );
4744 const bool container = has_flag_ter_or_furn( container_string, p );
4745 const bool sealed = has_flag_ter_or_furn( TFLAG_SEALED, p );
4746 if( sealed && container ) {
4747 // never see inside of sealed containers
4748 return false;
4749 }
4750 if( container ) {
4751 // can see inside of containers if adjacent or
4752 // on top of the container
4753 return ( std::abs( p.x - from.x ) <= 1 &&
4754 std::abs( p.y - from.y ) <= 1 &&
4755 std::abs( p.z - from.z ) <= 1 );
4756 }
4757 return true;
4758}
bool has_flag_ter_or_furn(const std::string &flag, const tripoint &p) const
Definition: map.cpp:2322
@ TFLAG_SEALED
Definition: mapdata.h:285

References has_flag_ter_or_furn(), TFLAG_SEALED, tripoint::x, tripoint::y, and tripoint::z.

◆ coverage()

int map::coverage ( const tripoint p) const

Returns coverage value of the tile.

Definition at line 6244 of file map.cpp.

6245{
6246 if( const auto obstacle_f = furn( p ) ) {
6247 return obstacle_f->coverage;
6248 }
6249 if( const auto vp = veh_at( p ) ) {
6250 if( vp->obstacle_at_part() ) {
6251 return 60;
6252 } else if( !vp->part_with_feature( VPFLAG_AISLE, true ) ) {
6253 return 45;
6254 }
6255 }
6256 return ter( p )->coverage;
6257}
@ VPFLAG_AISLE
Definition: veh_type.h:40

References map_data_common_t::coverage, furn(), ter(), veh_at(), and VPFLAG_AISLE.

Referenced by build_vision_transparency_cache(), and game::print_terrain_info().

◆ create_anomaly() [1/2]

void map::create_anomaly ( const point cp,
artifact_natural_property  prop,
bool  create_rubble = true 
)
inline

Definition at line 1392 of file map.h.

1392 {
1393 create_anomaly( tripoint( cp, abs_sub.z ), prop, create_rubble );
1394 }
void create_anomaly(const tripoint &p, artifact_natural_property prop, bool create_rubble=true)
Definition: mapgen.cpp:6324

References abs_sub, create_anomaly(), and tripoint::z.

◆ create_anomaly() [2/2]

void map::create_anomaly ( const tripoint p,
artifact_natural_property  prop,
bool  create_rubble = true 
)

Definition at line 6324 of file mapgen.cpp.

6325{
6326 // TODO: Z
6327 point c( cp.xy() );
6328 if( create_rubble ) {
6329 rough_circle( this, t_dirt, c, 11 );
6330 rough_circle_furn( this, f_rubble, c, 5 );
6331 furn_set( c, f_null );
6332 }
6333 switch( prop ) {
6334 case ARTPROP_WRIGGLING:
6335 case ARTPROP_MOVING:
6336 for( int i = c.x - 5; i <= c.x + 5; i++ ) {
6337 for( int j = c.y - 5; j <= c.y + 5; j++ ) {
6338 if( furn( point( i, j ) ) == f_rubble ) {
6339 add_field( {i, j, abs_sub.z}, fd_push_items, 1 );
6340 if( one_in( 3 ) ) {
6341 spawn_item( point( i, j ), "rock" );
6342 }
6343 }
6344 }
6345 }
6346 break;
6347
6348 case ARTPROP_GLOWING:
6349 case ARTPROP_GLITTERING:
6350 for( int i = c.x - 5; i <= c.x + 5; i++ ) {
6351 for( int j = c.y - 5; j <= c.y + 5; j++ ) {
6352 if( furn( point( i, j ) ) == f_rubble && one_in( 2 ) ) {
6353 mtrap_set( this, point( i, j ), tr_glow );
6354 }
6355 }
6356 }
6357 break;
6358
6359 case ARTPROP_HUMMING:
6360 case ARTPROP_RATTLING:
6361 for( int i = c.x - 5; i <= c.x + 5; i++ ) {
6362 for( int j = c.y - 5; j <= c.y + 5; j++ ) {
6363 if( furn( point( i, j ) ) == f_rubble && one_in( 2 ) ) {
6364 mtrap_set( this, point( i, j ), tr_hum );
6365 }
6366 }
6367 }
6368 break;
6369
6370 case ARTPROP_WHISPERING:
6371 case ARTPROP_ENGRAVED:
6372 for( int i = c.x - 5; i <= c.x + 5; i++ ) {
6373 for( int j = c.y - 5; j <= c.y + 5; j++ ) {
6374 if( furn( point( i, j ) ) == f_rubble && one_in( 3 ) ) {
6375 mtrap_set( this, point( i, j ), tr_shadow );
6376 }
6377 }
6378 }
6379 break;
6380
6381 case ARTPROP_BREATHING:
6382 for( int i = c.x - 1; i <= c.x + 1; i++ ) {
6383 for( int j = c.y - 1; j <= c.y + 1; j++ ) {
6384 if( i == c.x && j == c.y ) {
6385 place_spawns( GROUP_BREATHER_HUB, 1, point( i, j ), point( i, j ), 1,
6386 true );
6387 } else {
6388 place_spawns( GROUP_BREATHER, 1, point( i, j ), point( i, j ), 1, true );
6389 }
6390 }
6391 }
6392 break;
6393
6394 case ARTPROP_DEAD:
6395 for( int i = c.x - 5; i <= c.x + 5; i++ ) {
6396 for( int j = c.y - 5; j <= c.y + 5; j++ ) {
6397 if( furn( point( i, j ) ) == f_rubble ) {
6398 mtrap_set( this, point( i, j ), tr_drain );
6399 }
6400 }
6401 }
6402 break;
6403
6404 case ARTPROP_ITCHY:
6405 for( int i = c.x - 5; i <= c.x + 5; i++ ) {
6406 for( int j = c.y - 5; j <= c.y + 5; j++ ) {
6407 if( furn( point( i, j ) ) == f_rubble ) {
6408 set_radiation( point( i, j ), rng( 0, 10 ) );
6409 }
6410 }
6411 }
6412 break;
6413
6414 case ARTPROP_ELECTRIC:
6415 case ARTPROP_CRACKLING:
6416 add_field( {c, abs_sub.z}, fd_shock_vent, 3 );
6417 break;
6418
6419 case ARTPROP_SLIMY:
6420 add_field( {c, abs_sub.z}, fd_acid_vent, 3 );
6421 break;
6422
6423 case ARTPROP_WARM:
6424 for( int i = c.x - 5; i <= c.x + 5; i++ ) {
6425 for( int j = c.y - 5; j <= c.y + 5; j++ ) {
6426 if( furn( point( i, j ) ) == f_rubble ) {
6427 add_field( {i, j, abs_sub.z}, fd_fire_vent, 1 + ( rl_dist( c, point( i, j ) ) % 3 ) );
6428 }
6429 }
6430 }
6431 break;
6432
6433 case ARTPROP_SCALED:
6434 for( int i = c.x - 5; i <= c.x + 5; i++ ) {
6435 for( int j = c.y - 5; j <= c.y + 5; j++ ) {
6436 if( furn( point( i, j ) ) == f_rubble ) {
6437 mtrap_set( this, point( i, j ), tr_snake );
6438 }
6439 }
6440 }
6441 break;
6442
6443 case ARTPROP_FRACTAL:
6444 create_anomaly( c + point( -4, -4 ),
6445 static_cast<artifact_natural_property>( rng( ARTPROP_NULL + 1, ARTPROP_MAX - 1 ) ) );
6446 create_anomaly( c + point( 4, -4 ),
6447 static_cast<artifact_natural_property>( rng( ARTPROP_NULL + 1, ARTPROP_MAX - 1 ) ) );
6448 create_anomaly( c + point( -4, 4 ),
6449 static_cast<artifact_natural_property>( rng( ARTPROP_NULL + 1, ARTPROP_MAX - 1 ) ) );
6450 create_anomaly( c + point( 4, -4 ),
6451 static_cast<artifact_natural_property>( rng( ARTPROP_NULL + 1, ARTPROP_MAX - 1 ) ) );
6452 break;
6453 default:
6454 break;
6455 }
6456}
bool add_field(const tripoint &p, const field_type_id &type_id, int intensity=INT_MAX, const time_duration &age=0_turns, bool hit_player=true)
Add field entry at point, or set intensity if present.
Definition: map.cpp:5396
void place_spawns(const mongroup_id &group, int chance, const point &p1, const point &p2, float density, bool individual=false, bool friendly=false, const std::string &name="NONE", int mission_id=-1)
Definition: mapgen.cpp:5393
void set_radiation(const tripoint &p, int value)
Definition: map.cpp:4035
void spawn_item(const tripoint &p, const itype_id &type_id, unsigned quantity=1, int charges=0, const time_point &birthday=calendar::start_of_cataclysm, int damlevel=0)
Definition: map.cpp:4183
artifact_natural_property
Definition: enums.h:152
@ ARTPROP_GLITTERING
Definition: enums.h:162
@ ARTPROP_ITCHY
Definition: enums.h:161
@ ARTPROP_RATTLING
Definition: enums.h:168
@ ARTPROP_WRIGGLING
Definition: enums.h:154
@ ARTPROP_HUMMING
Definition: enums.h:156
@ ARTPROP_WHISPERING
Definition: enums.h:158
@ ARTPROP_ENGRAVED
Definition: enums.h:165
@ ARTPROP_ELECTRIC
Definition: enums.h:163
@ ARTPROP_FRACTAL
Definition: enums.h:170
@ ARTPROP_SCALED
Definition: enums.h:169
@ ARTPROP_GLOWING
Definition: enums.h:155
@ ARTPROP_NULL
Definition: enums.h:153
@ ARTPROP_DEAD
Definition: enums.h:160
@ ARTPROP_BREATHING
Definition: enums.h:159
@ ARTPROP_MAX
Definition: enums.h:171
@ ARTPROP_CRACKLING
Definition: enums.h:166
@ ARTPROP_WARM
Definition: enums.h:167
@ ARTPROP_MOVING
Definition: enums.h:157
@ ARTPROP_SLIMY
Definition: enums.h:164
field_type_id fd_fire_vent
Definition: field_type.cpp:351
field_type_id fd_acid_vent
Definition: field_type.cpp:357
field_type_id fd_push_items
Definition: field_type.cpp:355
field_type_id fd_shock_vent
Definition: field_type.cpp:356
furn_id f_rubble
Definition: mapdata.cpp:1097
void rough_circle(map *m, const ter_id &type, const point &p, int rad)
Definition: mapgen.cpp:6491
void rough_circle_furn(map *m, const furn_id &type, const point &p, int rad)
Definition: mapgen.cpp:6495
static const mongroup_id GROUP_BREATHER("GROUP_BREATHER")
static const mongroup_id GROUP_BREATHER_HUB("GROUP_BREATHER_HUB")
void mtrap_set(map *m, const point &p, trap_id type)
static const trap_str_id tr_drain("tr_drain")
static const trap_str_id tr_snake("tr_snake")
static const trap_str_id tr_shadow("tr_shadow")
trap_id tr_glow
Definition: trap.cpp:312
trap_id tr_hum
Definition: trap.cpp:313

References abs_sub, add_field(), ARTPROP_BREATHING, ARTPROP_CRACKLING, ARTPROP_DEAD, ARTPROP_ELECTRIC, ARTPROP_ENGRAVED, ARTPROP_FRACTAL, ARTPROP_GLITTERING, ARTPROP_GLOWING, ARTPROP_HUMMING, ARTPROP_ITCHY, ARTPROP_MAX, ARTPROP_MOVING, ARTPROP_NULL, ARTPROP_RATTLING, ARTPROP_SCALED, ARTPROP_SLIMY, ARTPROP_WARM, ARTPROP_WHISPERING, ARTPROP_WRIGGLING, c, create_anomaly(), f_null, f_rubble, fd_acid_vent, fd_fire_vent, fd_push_items, fd_shock_vent, furn(), furn_set(), GROUP_BREATHER, GROUP_BREATHER_HUB, mtrap_set(), one_in(), place_spawns(), rl_dist(), rng(), rough_circle(), rough_circle_furn(), set_radiation(), spawn_item(), t_dirt, tr_drain, tr_glow, tr_hum, tr_shadow, tr_snake, tripoint::xy(), and tripoint::z.

Referenced by create_anomaly(), debug_menu::debug(), draw_lab(), and MapExtras::mx_portal_in().

◆ create_burnproducts()

void map::create_burnproducts ( const tripoint p,
const item fuel,
const units::mass burned_mass 
)

Definition at line 96 of file map_field.cpp.

97{
98 std::vector<material_id> all_mats = fuel.made_of();
99 if( all_mats.empty() ) {
100 return;
101 }
102 // Items that are multiple materials are assumed to be equal parts each.
103 const units::mass by_weight = burned_mass / all_mats.size();
104 for( material_id &mat : all_mats ) {
105 for( auto &bp : mat->burn_products() ) {
106 itype_id id = bp.first;
107 // Spawning the same item as the one that was just burned is pointless
108 // and leads to infinite recursion.
109 if( fuel.typeId() == id ) {
110 continue;
111 }
112 const float eff = bp.second;
113 const int n = std::floor( eff * ( by_weight / id->weight ) );
114
115 if( n <= 0 ) {
116 continue;
117 }
118 spawn_item( p, id, n, 1, calendar::turn );
119 }
120 }
121}
const std::string id
Definition: basecamp.h:87

References base_camps::id, item::made_of(), spawn_item(), calendar::turn, and item::typeId().

Referenced by MapExtras::burned_ground_parser(), and process_fields_in_submap().

◆ create_hot_air()

void map::create_hot_air ( const tripoint p,
int  intensity 
)
private

Definition at line 363 of file map_field.cpp.

364{
365 field_type_id hot_air;
366 switch( intensity ) {
367 case 1:
368 hot_air = fd_hot_air1;
369 break;
370 case 2:
371 hot_air = fd_hot_air2;
372 break;
373 case 3:
374 hot_air = fd_hot_air3;
375 break;
376 case 4:
377 hot_air = fd_hot_air4;
378 break;
379 default:
380 debugmsg( "Tried to spread hot air with intensity %d", intensity );
381 return;
382 }
383
384 for( int counter = 0; counter < 5; counter++ ) {
385 tripoint dst( p + point( rng( -1, 1 ), rng( -1, 1 ) ) );
386 add_field( dst, hot_air, 1 );
387 }
388}
field_type_id fd_hot_air3
Definition: field_type.cpp:381
field_type_id fd_hot_air2
Definition: field_type.cpp:380
field_type_id fd_hot_air1
Definition: field_type.cpp:379
field_type_id fd_hot_air4
Definition: field_type.cpp:382

References add_field(), debugmsg, fd_hot_air1, fd_hot_air2, fd_hot_air3, fd_hot_air4, and rng().

Referenced by process_fields_in_submap().

◆ creature_in_field()

void map::creature_in_field ( Creature critter)

Apply field effects to the creature when it's on a square with fields.

Definition at line 1563 of file map_field.cpp.

1564{
1565 bool in_vehicle = false;
1566 bool inside_vehicle = false;
1567 player *u = critter.as_player();
1568 if( critter.is_monster() ) {
1569 monster_in_field( *static_cast<monster *>( &critter ) );
1570 } else {
1571 if( u ) {
1572 in_vehicle = u->in_vehicle;
1573 // If we are in a vehicle figure out if we are inside (reduces effects usually)
1574 // and what part of the vehicle we need to deal with.
1575 if( in_vehicle ) {
1576 if( const optional_vpart_position vp = veh_at( u->pos() ) ) {
1577 if( vp->is_inside() ) {
1578 inside_vehicle = true;
1579 }
1580 }
1581 }
1582 player_in_field( *u );
1583 }
1584 }
1585
1586 field &curfield = get_field( critter.pos() );
1587 for( auto &field_entry_it : curfield ) {
1588 field_entry &cur_field_entry = field_entry_it.second;
1589 if( !cur_field_entry.is_field_alive() ) {
1590 continue;
1591 }
1592 const field_type_id cur_field_id = cur_field_entry.get_field_type();
1593
1594 for( const auto &fe : cur_field_entry.field_effects() ) {
1595 if( in_vehicle && fe.immune_in_vehicle ) {
1596 continue;
1597 }
1598 if( inside_vehicle && fe.immune_inside_vehicle ) {
1599 continue;
1600 }
1601 if( !inside_vehicle && fe.immune_outside_vehicle ) {
1602 continue;
1603 }
1604 if( in_vehicle && !one_in( fe.chance_in_vehicle ) ) {
1605 continue;
1606 }
1607 if( inside_vehicle && !one_in( fe.chance_inside_vehicle ) ) {
1608 continue;
1609 }
1610 if( !inside_vehicle && !one_in( fe.chance_outside_vehicle ) ) {
1611 continue;
1612 }
1613
1614 const effect field_fx = fe.get_effect();
1615 if( critter.is_immune_field( cur_field_id ) || critter.is_immune_effect( field_fx.get_id() ) ) {
1616 continue;
1617 }
1618 bool effect_added = false;
1619 if( fe.is_environmental ) {
1620 effect_added = critter.add_env_effect( fe.id, fe.bp->token, fe.intensity, fe.get_duration() );
1621 } else {
1622 effect_added = true;
1623 critter.add_effect( field_fx );
1624 }
1625 if( effect_added ) {
1626 critter.add_msg_player_or_npc( fe.env_message_type, fe.get_message(), fe.get_message_npc() );
1627 }
1628 }
1629 }
1630}
bool in_vehicle
Definition: character.h:1511
virtual bool is_monster() const
Definition: creature.h:101
virtual bool is_immune_field(const field_type_id &) const
Returns true if we are immune to the field type with the given fid.
Definition: creature.h:325
virtual void add_msg_player_or_npc(const std::string &, const std::string &) const
Definition: creature.h:677
virtual player * as_player()
Definition: creature.h:122
virtual bool is_immune_effect(const efftype_id &type) const =0
Definition: effect.h:161
const efftype_id & get_id() const
Returns the effect's matching effect_type id.
Definition: effect.h:305
std::vector< field_effect > field_effects() const
Definition: field.cpp:294
bool is_field_alive()
Definition: field.h:89
field_type_id get_field_type() const
Definition: field.cpp:105
A variable sized collection of field entries on a given map square.
Definition: field.h:131
void player_in_field(player &u)
Definition: map_field.cpp:1224
void monster_in_field(monster &z)
Definition: map_field.cpp:1632

References Creature::add_effect(), Creature::add_env_effect(), Creature::add_msg_player_or_npc(), Creature::as_player(), field_entry::field_effects(), get_field(), field_entry::get_field_type(), effect::get_id(), Character::in_vehicle, field_entry::is_field_alive(), Creature::is_immune_effect(), Creature::is_immune_field(), Creature::is_monster(), monster_in_field(), one_in(), player_in_field(), Creature::pos(), Character::pos(), and veh_at().

Referenced by add_field(), game::do_turn(), game::monmove(), npc::move_to(), and game::place_player().

◆ creature_on_trap()

void map::creature_on_trap ( Creature critter,
bool  may_avoid = true 
)

Apply trap effects to the creature, similar to creature_in_field.

If there is no trap at the creatures location, nothing is done. If the creature can avoid the trap, nothing is done as well. Otherwise the trap is triggered.

Parameters
critterCreature that just got trapped
may_avoidIf true, the creature tries to avoid the trap (Creature::avoid_trap). If false, the trap is always triggered.

Definition at line 8472 of file map.cpp.

8473{
8474 const auto &tr = tr_at( c.pos() );
8475 if( tr.is_null() ) {
8476 return;
8477 }
8478 // boarded in a vehicle means the player is above the trap, like a flying monster and can
8479 // never trigger the trap.
8480 const player *const p = dynamic_cast<const player *>( &c );
8481 if( p != nullptr && p->in_vehicle ) {
8482 return;
8483 }
8484 if( may_avoid && c.avoid_trap( c.pos(), tr ) ) {
8485 return;
8486 }
8487 tr.trigger( c.pos(), &c );
8488}

References c, Character::in_vehicle, and tr_at().

Referenced by game::fling_creature(), iexamine::ledge(), npc::move_to(), game::phasing_move(), game::place_player(), mattack::ranged_pull(), smash(), and game::vertical_move().

◆ crush()

void map::crush ( const tripoint p)

Definition at line 3661 of file map.cpp.

3662{
3663 player *crushed_player = g->critter_at<player>( p );
3664
3665 if( crushed_player != nullptr ) {
3666 bool player_inside = false;
3667 if( crushed_player->in_vehicle ) {
3668 const optional_vpart_position vp = veh_at( p );
3669 player_inside = vp && vp->is_inside();
3670 }
3671 if( !player_inside ) { //If there's a player at p and he's not in a covered vehicle...
3672 //This is the roof coming down on top of us, no chance to dodge
3673 crushed_player->add_msg_player_or_npc( m_bad, _( "You are crushed by the falling debris!" ),
3674 _( "<npcname> is crushed by the falling debris!" ) );
3675 // TODO: Make this depend on the ceiling material
3676 const int dam = rng( 0, 40 );
3677 // Torso and head take the brunt of the blow
3678 crushed_player->deal_damage( nullptr, bodypart_id( "head" ), damage_instance( DT_BASH,
3679 dam * .25 ) );
3680 crushed_player->deal_damage( nullptr, bodypart_id( "torso" ), damage_instance( DT_BASH,
3681 dam * .45 ) );
3682 // Legs take the next most through transferred force
3683 crushed_player->deal_damage( nullptr, bodypart_id( "leg_l" ), damage_instance( DT_BASH,
3684 dam * .10 ) );
3685 crushed_player->deal_damage( nullptr, bodypart_id( "leg_r" ), damage_instance( DT_BASH,
3686 dam * .10 ) );
3687 // Arms take the least
3688 crushed_player->deal_damage( nullptr, bodypart_id( "arm_l" ), damage_instance( DT_BASH,
3689 dam * .05 ) );
3690 crushed_player->deal_damage( nullptr, bodypart_id( "arm_r" ), damage_instance( DT_BASH,
3691 dam * .05 ) );
3692
3693 // Pin whoever got hit
3694 crushed_player->add_effect( effect_crushed, 1_turns, num_bp );
3695 crushed_player->check_dead_state();
3696 }
3697 }
3698
3699 if( monster *const monhit = g->critter_at<monster>( p ) ) {
3700 // 25 ~= 60 * .45 (torso)
3701 monhit->deal_damage( nullptr, bodypart_id( "torso" ), damage_instance( DT_BASH, rng( 0, 25 ) ) );
3702
3703 // Pin whoever got hit
3704 monhit->add_effect( effect_crushed, 1_turns, num_bp );
3705 monhit->check_dead_state();
3706 }
3707
3708 if( const optional_vpart_position vp = veh_at( p ) ) {
3709 // Arbitrary number is better than collapsing house roof crushing APCs
3710 vp->vehicle().damage( vp->part_index(), rng( 100, 1000 ), DT_BASH, false );
3711 }
3712}
int_id< body_part_type > bodypart_id
Definition: bodypart.h:23
@ num_bp
Definition: bodypart.h:52
void check_dead_state()
This function checks the creatures is_dead_state and (if true) calls die.
Definition: creature.cpp:1839
void add_msg_player_or_npc(const std::string &player_msg, const std::string &npc_str) const override
Definition: player.cpp:3978
@ m_bad
Definition: enums.h:261
static const efftype_id effect_crushed("crushed")

References _, Creature::add_effect(), player::add_msg_player_or_npc(), Creature::check_dead_state(), Character::deal_damage(), DT_BASH, effect_crushed, g, Character::in_vehicle, m_bad, num_bp, rng(), and veh_at().

Referenced by collapse_at().

◆ dangerous_field_at()

bool map::dangerous_field_at ( const tripoint p)

Definition at line 5385 of file map.cpp.

5386{
5387 for( auto &pr : field_at( p ) ) {
5388 auto &fd = pr.second;
5389 if( fd.is_dangerous() ) {
5390 return true;
5391 }
5392 }
5393 return false;
5394}
const field & field_at(const tripoint &p) const
Get the fields that are here.
Definition: map.cpp:5287

References field_at().

Referenced by are_requirements_nearby(), and generic_multi_activity_locations().

◆ decay_cosmetic_fields()

void map::decay_cosmetic_fields ( const tripoint p,
const time_duration time_since_last_actualize 
)
protected

Definition at line 7386 of file map.cpp.

7388{
7389 for( auto &pr : field_at( p ) ) {
7390 auto &fd = pr.second;
7391 const time_duration hl = fd.get_field_type().obj().half_life;
7392 if( !fd.decays_on_actualize() || hl <= 0_turns ) {
7393 continue;
7394 }
7395
7396 const time_duration added_age = 2 * time_since_last_actualize / rng( 2, 4 );
7397 fd.mod_field_age( added_age );
7398 const int intensity_drop = fd.get_field_age() / hl;
7399 if( intensity_drop > 0 ) {
7400 fd.set_field_intensity( fd.get_field_intensity() - intensity_drop );
7401 fd.mod_field_age( -hl * intensity_drop );
7402 }
7403 }
7404}

References field_at(), and rng().

Referenced by actualize().

◆ decay_fields_and_scent()

void map::decay_fields_and_scent ( const time_duration amount)

Moved here from weather.cpp for speed.

Decays fire, washable fields and scent. Washable fields are decayed only by 1/3 of the amount fire is.

Definition at line 2663 of file map.cpp.

2664{
2665 // TODO: Make this happen on all z-levels
2666
2667 // Decay scent separately, so that later we can use field count to skip empty submaps
2668 g->scent.decay();
2669
2670 // Coordinate code copied from lightmap calculations
2671 // TODO: Z
2672 const int smz = abs_sub.z;
2673 const auto &outside_cache = get_cache_ref( smz ).outside_cache;
2674 for( int smx = 0; smx < my_MAPSIZE; ++smx ) {
2675 for( int smy = 0; smy < my_MAPSIZE; ++smy ) {
2676 const auto cur_submap = get_submap_at_grid( { smx, smy, smz } );
2677 int to_proc = cur_submap->field_count;
2678 if( to_proc < 1 ) {
2679 if( to_proc < 0 ) {
2680 cur_submap->field_count = 0;
2681 dbg( DL::Error ) << "map::decay_fields_and_scent: submap at "
2682 << ( abs_sub + tripoint( smx, smy, 0 ) )
2683 << "has " << to_proc << " field_count";
2684 }
2685 get_cache( smz ).field_cache.reset( smx + ( smy * MAPSIZE ) );
2686 // This submap has no fields
2687 continue;
2688 }
2689
2690 for( int sx = 0; sx < SEEX; ++sx ) {
2691 if( to_proc < 1 ) {
2692 // This submap had some fields, but all got proc'd already
2693 break;
2694 }
2695
2696 for( int sy = 0; sy < SEEY; ++sy ) {
2697 const int x = sx + smx * SEEX;
2698 const int y = sy + smy * SEEY;
2699
2700 field &fields = cur_submap->get_field( { sx, sy} );
2701 if( !outside_cache[x][y] ) {
2702 to_proc -= fields.field_count();
2703 continue;
2704 }
2705
2706 for( auto &fp : fields ) {
2707 to_proc--;
2708 field_entry &cur = fp.second;
2709 const field_type_id type = cur.get_field_type();
2710 const int decay_amount_factor = type.obj().decay_amount_factor;
2711 if( decay_amount_factor != 0 ) {
2712 const time_duration decay_amount = amount / decay_amount_factor;
2713 cur.set_field_age( cur.get_field_age() + decay_amount );
2714 }
2715 }
2716 }
2717 }
2718
2719 if( to_proc > 0 ) {
2720 cur_submap->field_count = cur_submap->field_count - to_proc;
2721 dbg( DL::Error ) << "map::decay_fields_and_scent: submap at "
2722 << abs_sub + tripoint( smx, smy, 0 )
2723 << "has " << cur_submap->field_count - to_proc << "fields, but "
2724 << cur_submap->field_count << " field_count";
2725 }
2726 }
2727 }
2728}
time_duration set_field_age(const time_duration &new_age)
Sets age to the given value.
Definition: field.cpp:138
time_duration get_field_age() const
Definition: field.cpp:133
@ Error
Error (default: enabled).

References abs_sub, dbg, Error, level_cache::field_cache, submap::field_count, g, get_cache(), get_cache_ref(), field_entry::get_field_age(), field_entry::get_field_type(), get_submap_at_grid(), MAPSIZE, my_MAPSIZE, level_cache::outside_cache, SEEX, SEEY, field_entry::set_field_age(), sx, sy, type, and tripoint::z.

◆ delete_graffiti()

void map::delete_graffiti ( const tripoint p)

Definition at line 7812 of file map.cpp.

7813{
7814 if( !inbounds( p ) ) {
7815 return;
7816 }
7817 point l;
7818 submap *const current_submap = get_submap_at( p, l );
7819 current_submap->delete_graffiti( l );
7820}
void delete_graffiti(const point &p)
Definition: submap.cpp:109

References submap::delete_graffiti(), get_submap_at(), and inbounds().

◆ delete_signage()

void map::delete_signage ( const tripoint p) const

Definition at line 4011 of file map.cpp.

4012{
4013 if( !inbounds( p ) ) {
4014 return;
4015 }
4016
4017 point l;
4018 submap *const current_submap = get_submap_at( p, l );
4019
4020 current_submap->delete_signage( l );
4021}
void delete_signage(const point &p)
Definition: submap.cpp:148

References submap::delete_signage(), get_submap_at(), and inbounds().

Referenced by bash_furn_success(), construct::done_deconstruct(), and talk_function::loot_building().

◆ deregister_vehicle_zone()

bool map::deregister_vehicle_zone ( zone_data zone)

Definition at line 963 of file map.cpp.

964{
966 zone.get_start_point() ) ).part_with_feature( "CARGO", false ) ) {
967 auto bounds = vp->vehicle().loot_zones.equal_range( vp->mount() );
968 for( auto it = bounds.first; it != bounds.second; it++ ) {
969 if( &zone == &( it->second ) ) {
970 vp->vehicle().loot_zones.erase( it );
971 return true;
972 }
973 }
974 }
975 return false;
976}
tripoint getlocal(const tripoint &p) const
Inverse of getabs.
Definition: map.cpp:8266
tripoint get_start_point() const
Definition: clzones.h:314

References zone_data::get_start_point(), getlocal(), optional_vpart_position::part_with_feature(), and veh_at().

◆ destroy()

void map::destroy ( const tripoint p,
bool  silent = false 
)

Keeps bashing a square until it can't be bashed anymore.

Definition at line 3627 of file map.cpp.

3628{
3629 // Break if it takes more than 25 destructions to remove to prevent infinite loops
3630 // Example: A bashes to B, B bashes to A leads to A->B->A->...
3631
3632 // If we were destroying a floor, allow destroying floors
3633 // If we were destroying something unpassable, destroy only that
3634 bool was_impassable = impassable( p );
3635 int count = 0;
3636 while( count <= 25
3637 && bash( p, 999, silent, true ).success
3638 && ( !was_impassable || impassable( p ) ) ) {
3639 count++;
3640 }
3641}

References bash(), detail::count(), impassable(), silent, and behavior::success.

Referenced by add_vehicle_to_map(), bash(), MapExtras::burned_ground_parser(), activity_handlers::burrow_finish(), collapse_at(), draw_lab(), activity_handlers::jackhammer_finish(), make_rubble(), MapExtras::mx_crater(), MapExtras::mx_helicopter(), MapExtras::mx_supplydrop(), om_cutdown_trees(), activity_handlers::pickaxe_finish(), process_fields_in_submap(), and explosion_handler::explosion_funcs::resonance_cascade().

◆ destroy_furn()

void map::destroy_furn ( const tripoint p,
bool  silent = false 
)

Keeps bashing a square until there is no more furniture.

Definition at line 3643 of file map.cpp.

3644{
3645 // Break if it takes more than 25 destructions to remove to prevent infinite loops
3646 // Example: A bashes to B, B bashes to A leads to A->B->A->...
3647 int count = 0;
3648 while( count <= 25 && furn( p ) != f_null && bash( p, 999, silent, true ).success ) {
3649 count++;
3650 }
3651}

References bash(), detail::count(), f_null, furn(), silent, and behavior::success.

Referenced by construct::done_grave(), and make_rubble().

◆ destroy_vehicle()

◆ detach_vehicle()

std::unique_ptr< vehicle > map::detach_vehicle ( vehicle veh)

Definition at line 354 of file map.cpp.

355{
356 if( veh == nullptr ) {
357 debugmsg( "map::detach_vehicle was passed nullptr" );
358 return std::unique_ptr<vehicle>();
359 }
360
361 int z = veh->sm_pos.z;
362 if( z < -OVERMAP_DEPTH || z > OVERMAP_HEIGHT ) {
363 debugmsg( "detach_vehicle got a vehicle outside allowed z-level range! name=%s, submap:%d,%d,%d",
364 veh->name, veh->sm_pos.x, veh->sm_pos.y, veh->sm_pos.z );
365 // Try to fix by moving the vehicle here
366 z = veh->sm_pos.z = abs_sub.z;
367 }
368
369 // Unboard all passengers before detaching
370 for( auto const &part : veh->get_avail_parts( VPFLAG_BOARDABLE ) ) {
371 player *passenger = part.get_passenger();
372 if( passenger ) {
373 unboard_vehicle( part, passenger );
374 }
375 }
376 veh->invalidate_towing( true );
377 submap *const current_submap = get_submap_at_grid( veh->sm_pos );
378 level_cache &ch = get_cache( z );
379 for( size_t i = 0; i < current_submap->vehicles.size(); i++ ) {
380 if( current_submap->vehicles[i].get() == veh ) {
381 ch.vehicle_list.erase( veh );
382 ch.zone_vehicles.erase( veh );
384 std::unique_ptr<vehicle> result = std::move( current_submap->vehicles[i] );
385 current_submap->vehicles.erase( current_submap->vehicles.begin() + i );
386 if( veh->tracking_on ) {
388 }
389 dirty_vehicle_list.erase( veh );
390 veh->detach();
391 veh->refresh_position();
392 return result;
393 }
394 }
395 debugmsg( "detach_vehicle can't find it! name=%s, submap:%d,%d,%d", veh->name, veh->sm_pos.x,
396 veh->sm_pos.y, veh->sm_pos.z );
397 return std::unique_ptr<vehicle>();
398}
std::set< vehicle * > dirty_vehicle_list
Definition: map.h:1648
void reset_vehicle_cache()
Definition: map.cpp:254
void remove_vehicle(const vehicle *veh)
Remove the vehicle from being tracked in the overmap.
std::string name
Definition: vehicle.h:1849
void refresh_position()
Definition: vehicle.cpp:5815
bool tracking_on
Definition: vehicle.h:1991
void invalidate_towing(bool first_vehicle=false)
Definition: vehicle.cpp:6129
void detach()
Definition: vehicle.h:768
std::set< vehicle * > zone_vehicles
Definition: map.h:363
std::set< vehicle * > vehicle_list
Definition: map.h:362

References abs_sub, debugmsg, vehicle::detach(), dirty_vehicle_list, vehicle::get_avail_parts(), get_cache(), get_submap_at_grid(), vehicle::invalidate_towing(), avatar_action::move(), vehicle::name, overmap_buffer, OVERMAP_HEIGHT, vehicle::refresh_position(), overmapbuffer::remove_vehicle(), reset_vehicle_cache(), vehicle::sm_pos, vehicle::tracking_on, unboard_vehicle(), level_cache::vehicle_list, submap::vehicles, VPFLAG_BOARDABLE, tripoint::x, tripoint::y, tripoint::z, and level_cache::zone_vehicles.

Referenced by add_vehicle_to_map(), destroy_vehicle(), and editmap::mapgen_veh_destroy().

◆ determine_wall_corner()

int map::determine_wall_corner ( const tripoint p) const
private

Definition at line 7843 of file map.cpp.

7844{
7845 int test_connect_group = ter( p ).obj().connect_group;
7846 uint8_t connections = get_known_connections( p, test_connect_group );
7847 // The bits in connections are SEWN, whereas the characters in LINE_
7848 // constants are NESW, so we want values in 8 | 2 | 1 | 4 order.
7849 switch( connections ) {
7850 case 8 | 2 | 1 | 4:
7851 return LINE_XXXX;
7852 case 0 | 2 | 1 | 4:
7853 return LINE_OXXX;
7854
7855 case 8 | 0 | 1 | 4:
7856 return LINE_XOXX;
7857 case 0 | 0 | 1 | 4:
7858 return LINE_OOXX;
7859
7860 case 8 | 2 | 0 | 4:
7861 return LINE_XXOX;
7862 case 0 | 2 | 0 | 4:
7863 return LINE_OXOX;
7864 case 8 | 0 | 0 | 4:
7865 return LINE_XOOX;
7866 case 0 | 0 | 0 | 4:
7867 return LINE_OXOX; // LINE_OOOX would be better
7868
7869 case 8 | 2 | 1 | 0:
7870 return LINE_XXXO;
7871 case 0 | 2 | 1 | 0:
7872 return LINE_OXXO;
7873 case 8 | 0 | 1 | 0:
7874 return LINE_XOXO;
7875 case 0 | 0 | 1 | 0:
7876 return LINE_XOXO; // LINE_OOXO would be better
7877 case 8 | 2 | 0 | 0:
7878 return LINE_XXOO;
7879 case 0 | 2 | 0 | 0:
7880 return LINE_OXOX; // LINE_OXOO would be better
7881 case 8 | 0 | 0 | 0:
7882 return LINE_XOXO; // LINE_XOOO would be better
7883
7884 case 0 | 0 | 0 | 0:
7885 return ter( p ).obj().symbol(); // technically just a column
7886
7887 default:
7888 // assert( false );
7889 // this shall not happen
7890 return '?';
7891 }
7892}
uint8_t get_known_connections(const tripoint &p, int connect_group, const std::map< tripoint, ter_id > &override={}) const
Definition: map.cpp:1510
generic_factory< overmap_connection > connections("overmap connection")
#define LINE_XOXX
Definition: output.h:47
#define LINE_XOXO
Definition: output.h:39
#define LINE_OXOX
Definition: output.h:40
#define LINE_OOXX
Definition: output.h:43
#define LINE_OXXX
Definition: output.h:48
#define LINE_XXXO
Definition: output.h:45
#define LINE_XXOX
Definition: output.h:46
#define LINE_OXXO
Definition: output.h:42
#define LINE_XOOX
Definition: output.h:44
#define LINE_XXOO
Definition: output.h:41
#define LINE_XXXX
Definition: output.h:49
int symbol() const
Definition: mapdata.cpp:550

References map_data_common_t::connect_group, anonymous_namespace{overmap_connection.cpp}::connections, get_known_connections(), LINE_OOXX, LINE_OXOX, LINE_OXXO, LINE_OXXX, LINE_XOOX, LINE_XOXO, LINE_XOXX, LINE_XXOO, LINE_XXOX, LINE_XXXO, LINE_XXXX, int_id< T >::obj(), map_data_common_t::symbol(), and ter().

Referenced by draw_from_above(), and draw_maptile().

◆ disarm_trap()

void map::disarm_trap ( const tripoint p)
Perception increases chance of disarming trap Dexterity increases chance of disarming trap Traps increases chance of disarming trap

Definition at line 5203 of file map.cpp.

5204{
5205 const trap &tr = tr_at( p );
5206 if( tr.is_null() ) {
5207 debugmsg( "Tried to disarm a trap where there was none (%d %d %d)", p.x, p.y, p.z );
5208 return;
5209 }
5210
5211 const int tSkillLevel = g->u.get_skill_level( skill_traps );
5212 const int diff = tr.get_difficulty();
5213 int roll = rng( tSkillLevel, 4 * tSkillLevel );
5214
5215 // Some traps are not actual traps. Skip the rolls, different message and give the option to grab it right away.
5216 if( tr.get_avoidance() == 0 && tr.get_difficulty() == 0 ) {
5217 add_msg( _( "The %s is taken down." ), tr.name() );
5218 tr.on_disarmed( *this, p );
5219 return;
5220 }
5221
5222 ///\EFFECT_PER increases chance of disarming trap
5223
5224 ///\EFFECT_DEX increases chance of disarming trap
5225
5226 ///\EFFECT_TRAPS increases chance of disarming trap
5227 while( ( rng( 5, 20 ) < g->u.per_cur || rng( 1, 20 ) < g->u.dex_cur ) && roll < 50 ) {
5228 roll++;
5229 }
5230 if( roll >= diff ) {
5231 add_msg( _( "You disarm the trap!" ) );
5232 const int morale_buff = tr.get_avoidance() * 0.4 + tr.get_difficulty() + rng( 0, 4 );
5233 g->u.rem_morale( MORALE_FAILURE );
5234 g->u.add_morale( MORALE_ACCOMPLISHMENT, morale_buff, 40 );
5235 tr.on_disarmed( *this, p );
5236 if( diff > 1.25 * tSkillLevel ) { // failure might have set off trap
5237 g->u.practice( skill_traps, 1.5 * ( diff - tSkillLevel ) );
5238 }
5239 } else if( roll >= diff * .8 ) {
5240 add_msg( _( "You fail to disarm the trap." ) );
5241 const int morale_debuff = -rng( 6, 18 );
5242 g->u.rem_morale( MORALE_ACCOMPLISHMENT );
5243 g->u.add_morale( MORALE_FAILURE, morale_debuff, -40 );
5244 if( diff > 1.25 * tSkillLevel ) {
5245 g->u.practice( skill_traps, 1.5 * ( diff - tSkillLevel ) );
5246 }
5247 } else {
5248 add_msg( m_bad, _( "You fail to disarm the trap, and you set it off!" ) );
5249 const int morale_debuff = -rng( 12, 24 );
5250 g->u.rem_morale( MORALE_ACCOMPLISHMENT );
5251 g->u.add_morale( MORALE_FAILURE, morale_debuff, -40 );
5252 tr.trigger( p, &g->u );
5253 if( diff - roll <= 6 ) {
5254 // Give xp for failing, but not if we failed terribly (in which
5255 // case the trap may not be disarmable).
5256 g->u.practice( skill_traps, 2 * diff );
5257 }
5258 }
5259}
static const skill_id skill_traps("traps")
void add_msg(std::string msg)
Definition: messages.cpp:884
const morale_type MORALE_FAILURE("morale_failure")
const morale_type MORALE_ACCOMPLISHMENT("morale_accomplishment")
Definition: trap.h:86
std::string name() const
Definition: trap.cpp:177
int get_avoidance() const
Whether triggering the trap can be avoid (if greater than 0) and if so, this is compared to dodge ski...
Definition: trap.h:144
void trigger(const tripoint &pos, Creature *creature=nullptr, item *item=nullptr) const
Trigger trap effects.
Definition: trap.cpp:232
bool is_null() const
Whether this is the null-traps, aka no trap at all.
Definition: trap.cpp:245
void on_disarmed(map &m, const tripoint &p) const
Called when a trap at the given point in the map has been disarmed.
Definition: trap.cpp:260
int get_difficulty() const
This is used when disarming the trap.
Definition: trap.h:152

References _, add_msg(), debugmsg, g, trap::get_avoidance(), trap::get_difficulty(), trap::is_null(), m_bad, MORALE_ACCOMPLISHMENT, MORALE_FAILURE, trap::name(), trap::on_disarmed(), rng(), skill_traps, tr_at(), trap::trigger(), tripoint::x, tripoint::y, and tripoint::z.

Referenced by iexamine::trap().

◆ disp_name()

std::string map::disp_name ( const tripoint p)

Definition at line 1330 of file map.cpp.

1331{
1332 return string_format( _( "the %s" ), name( p ) );
1333}

References _, name(), and string_format().

Referenced by vehicle::part_collision().

◆ displace_vehicle()

bool map::displace_vehicle ( vehicle veh,
const tripoint dp 
)

Definition at line 1119 of file map.cpp.

1120{
1121 const tripoint src = veh.global_pos3();
1122
1123 tripoint dst = src + dp;
1124
1125 if( !inbounds( src ) ) {
1126 add_msg( m_debug, "map::displace_vehicle: coordinates out of bounds %d,%d,%d->%d,%d,%d",
1127 src.x, src.y, src.z, dst.x, dst.y, dst.z );
1128 return false;
1129 }
1130
1131 point src_offset;
1132 point dst_offset;
1133 submap *src_submap = get_submap_at( src, src_offset );
1134 submap *dst_submap = get_submap_at( dst, dst_offset );
1135 std::set<int> smzs;
1136
1137 // first, let's find our position in current vehicles vector
1138 size_t our_i = 0;
1139 bool found = false;
1140 for( auto &smap : grid ) {
1141 for( size_t i = 0; i < smap->vehicles.size(); i++ ) {
1142 if( smap->vehicles[i].get() == &veh ) {
1143 our_i = i;
1144 src_submap = smap;
1145 found = true;
1146 break;
1147 }
1148 }
1149 if( found ) {
1150 break;
1151 }
1152 }
1153
1154 if( !found ) {
1155 add_msg( m_debug, "displace_vehicle [%s] failed", veh.name );
1156 return false;
1157 }
1158
1159 // move the vehicle
1160 // don't let it go off grid
1161 if( !inbounds( dst ) ) {
1162 veh.stop();
1163 // Silent debug
1164 dbg( DL::Error ) << "map:displace_vehicle: Stopping vehicle, displaced dp=" << dp;
1165 return true;
1166 }
1167
1168 // Need old coordinates to check for remote control
1169 const bool remote = veh.remote_controlled( g->u );
1170
1171 // record every passenger and pet inside
1172 std::vector<rider_data> riders = veh.get_riders();
1173
1174 bool need_update = false;
1175 bool z_change = false;
1176 int z_to = 0;
1177 // Move passengers and pets
1178 bool complete = false;
1179 // loop until everyone has moved or for each passenger
1180 for( size_t i = 0; !complete && i < riders.size(); i++ ) {
1181 complete = true;
1182 for( rider_data &r : riders ) {
1183 if( r.moved ) {
1184 continue;
1185 }
1186 const int prt = r.prt;
1187
1188 Creature *psg = r.psg;
1189 const tripoint part_pos = veh.global_part_pos3( prt );
1190 if( psg == nullptr ) {
1191 debugmsg( "Empty passenger for part #%d at %d,%d,%d player at %d,%d,%d?",
1192 prt, part_pos.x, part_pos.y, part_pos.z,
1193 g->u.posx(), g->u.posy(), g->u.posz() );
1195 r.moved = true;
1196 continue;
1197 }
1198
1199 if( psg->pos() != part_pos ) {
1200 add_msg( m_debug, "Part/passenger position mismatch: part #%d at %d,%d,%d "
1201 "passenger at %d,%d,%d", prt, part_pos.x, part_pos.y, part_pos.z,
1202 psg->posx(), psg->posy(), psg->posz() );
1203 }
1204 const vehicle_part &veh_part = veh.part( prt );
1205
1206 tripoint next_pos = veh_part.precalc[1];
1207
1208 // Place passenger on the new part location
1209 tripoint psgp( dst + next_pos );
1210 // someone is in the way so try again
1211 if( g->critter_at( psgp ) ) {
1212 complete = false;
1213 continue;
1214 }
1215 if( psg->is_avatar() ) {
1216 // If passenger is you, we need to update the map
1217 need_update = true;
1218 z_change = psgp.z != part_pos.z;
1219 z_to = psgp.z;
1220 }
1221
1222 psg->setpos( psgp );
1223 r.moved = true;
1224 }
1225 }
1226
1227 veh.shed_loose_parts();
1228 smzs = veh.advance_precalc_mounts( dst_offset, src );
1229 if( src_submap != dst_submap ) {
1230 veh.set_submap_moved( tripoint( dst.x / SEEX, dst.y / SEEY, dst.z ) );
1231 auto src_submap_veh_it = src_submap->vehicles.begin() + our_i;
1232 dst_submap->vehicles.push_back( std::move( *src_submap_veh_it ) );
1233 src_submap->vehicles.erase( src_submap_veh_it );
1234 dst_submap->is_uniform = false;
1236 }
1237 if( need_update ) {
1238 g->update_map( g->u );
1239 }
1240 add_vehicle_to_cache( &veh );
1241
1242 if( z_change || src.z != dst.z ) {
1243 if( z_change ) {
1244 g->vertical_shift( z_to );
1245 // vertical moves can flush the caches, so make sure we're still in the cache
1246 add_vehicle_to_cache( &veh );
1247 }
1248 update_vehicle_list( dst_submap, dst.z );
1249 // delete the vehicle from the source z-level vehicle cache set if it is no longer on
1250 // that z-level
1251 if( src.z != dst.z ) {
1252 level_cache &ch2 = get_cache( src.z );
1253 for( const vehicle *elem : ch2.vehicle_list ) {
1254 if( elem == &veh ) {
1255 ch2.vehicle_list.erase( &veh );
1256 ch2.zone_vehicles.erase( &veh );
1257 break;
1258 }
1259 }
1260 }
1262 }
1263
1264 if( remote ) {
1265 // Has to be after update_map or coordinates won't be valid
1266 g->setremoteveh( &veh );
1267 }
1268
1269 //
1270 //global positions of vehicle loot zones have changed.
1271 veh.zones_dirty = true;
1272
1273 for( int vsmz : smzs ) {
1274 on_vehicle_moved( dst.z + vsmz );
1275 }
1276 return true;
1277}
virtual int posy() const =0
virtual int posz() const =0
virtual void setpos(const tripoint &pos)=0
virtual bool is_avatar() const
Definition: creature.h:95
virtual int posx() const =0
void on_vehicle_moved(int smz)
Callback invoked when a vehicle has moved.
Definition: map.cpp:405
void update_vehicle_list(const submap *to, int zlev)
Definition: map.cpp:340
tripoint global_pos3() const
Definition: vehicle.cpp:3281
bool check_is_heli_landed()
void shed_loose_parts()
Definition: vehicle.cpp:6257
std::vector< rider_data > get_riders() const
Definition: vehicle.cpp:3238
void stop(bool update_cache=true)
std::set< int > advance_precalc_mounts(const point &new_pos, const tripoint &src)
Definition: vehicle.cpp:7095
bool remote_controlled(const Character &p) const
Definition: vehicle.cpp:297
void set_submap_moved(const tripoint &p)
Update the submap coordinates and update the tracker info in the overmap (if enabled).
Definition: vehicle.cpp:3296
bool zones_dirty
Definition: vehicle.h:2007
@ m_debug
Definition: enums.h:271
Structure, describing vehicle part (i.e., wheel, seat)
Definition: vehicle.h:185
std::array< tripoint, 2 > precalc
mount translated to face.dir [0] and turn_dir [1]
Definition: vehicle.h:371
int remove_flag(const int flag) noexcept
Definition: vehicle.h:214

References add_msg(), add_vehicle_to_cache(), vehicle::advance_precalc_mounts(), vehicle::check_is_heli_landed(), dbg, debugmsg, Error, g, get_cache(), vehicle::get_riders(), get_submap_at(), vehicle::global_part_pos3(), vehicle::global_pos3(), grid, inbounds(), invalidate_max_populated_zlev(), Creature::is_avatar(), submap::is_uniform, m_debug, avatar_action::move(), vehicle::name, on_vehicle_moved(), vehicle::part(), vehicle_part::passenger_flag, Creature::pos(), Creature::posx(), Creature::posy(), Creature::posz(), vehicle_part::precalc, vehicle::remote_controlled(), vehicle_part::remove_flag(), SEEX, SEEY, vehicle::set_submap_moved(), Creature::setpos(), vehicle::shed_loose_parts(), vehicle::stop(), update_vehicle_list(), level_cache::vehicle_list, submap::vehicles, tripoint::x, tripoint::y, tripoint::z, level_cache::zone_vehicles, and vehicle::zones_dirty.

Referenced by game::grabbed_veh_move(), and move_vehicle().

◆ displace_water()

bool map::displace_water ( const tripoint dp)

Definition at line 1279 of file map.cpp.

1280{
1281 // Check for shallow water
1282 if( has_flag( "SWIMMABLE", p ) && !has_flag( TFLAG_DEEP_WATER, p ) ) {
1283 int dis_places = 0;
1284 int sel_place = 0;
1285 for( int pass = 0; pass < 2; pass++ ) {
1286 // we do 2 passes.
1287 // first, count how many non-water places around
1288 // then choose one within count and fill it with water on second pass
1289 if( pass != 0 ) {
1290 sel_place = rng( 0, dis_places - 1 );
1291 dis_places = 0;
1292 }
1293 for( const tripoint &temp : points_in_radius( p, 1 ) ) {
1294 if( temp != p
1295 || impassable_ter_furn( temp )
1296 || has_flag( TFLAG_DEEP_WATER, temp ) ) {
1297 continue;
1298 }
1299 ter_id ter0 = ter( temp );
1300 if( ter0 == t_water_sh ||
1301 ter0 == t_water_dp || ter0 == t_water_moving_sh || ter0 == t_water_moving_dp ) {
1302 continue;
1303 }
1304 if( pass != 0 && dis_places == sel_place ) {
1305 ter_set( temp, t_water_sh );
1306 ter_set( temp, t_dirt );
1307 return true;
1308 }
1309
1310 dis_places++;
1311 }
1312 }
1313 }
1314 return false;
1315}
ter_id t_water_moving_dp
Definition: mapdata.cpp:693
ter_id t_water_moving_sh
Definition: mapdata.cpp:693
ter_id t_water_dp
Definition: mapdata.cpp:693
ter_id t_water_sh
Definition: mapdata.cpp:693

References has_flag(), impassable_ter_furn(), points_in_radius(), rng(), t_dirt, t_water_dp, t_water_moving_dp, t_water_moving_sh, t_water_sh, ter(), ter_set(), and TFLAG_DEEP_WATER.

Referenced by move_vehicle().

◆ do_vehicle_caching()

void map::do_vehicle_caching ( int  z)

Definition at line 8198 of file map.cpp.

8199{
8200 level_cache &ch = get_cache( z );
8201 for( vehicle *v : ch.vehicle_list ) {
8202 for( const vpart_reference &vp : v->get_all_parts() ) {
8203 const tripoint &part_pos = v->global_part_pos3( vp.part() );
8204 if( !inbounds( part_pos.xy() ) || vp.part().removed ) {
8205 continue;
8206 }
8207 vehicle_caching_internal( get_cache( part_pos.z ), vp, v );
8208 if( part_pos.z < OVERMAP_HEIGHT ) {
8209 vehicle_caching_internal_above( get_cache( part_pos.z + 1 ), vp, v );
8210 }
8211 }
8212 }
8213}
static void vehicle_caching_internal_above(level_cache &zch_above, const vpart_reference &vp, vehicle *v)
Definition: map.cpp:8189
static void vehicle_caching_internal(level_cache &zch, const vpart_reference &vp, vehicle *v)
Definition: map.cpp:8122

References vehicle::get_all_parts(), get_cache(), vehicle::global_part_pos3(), inbounds(), OVERMAP_HEIGHT, vehicle_caching_internal(), vehicle_caching_internal_above(), level_cache::vehicle_list, tripoint::xy(), and tripoint::z.

Referenced by build_map_cache().

◆ dont_draw_lower_floor()

bool map::dont_draw_lower_floor ( const tripoint p)

Definition at line 5859 of file map.cpp.

5860{
5861 return !zlevels || p.z <= -OVERMAP_DEPTH ||
5863}
@ TFLAG_Z_TRANSPARENT
Definition: mapdata.h:321

References has_flag(), OVERMAP_DEPTH, TFLAG_NO_FLOOR, TFLAG_Z_TRANSPARENT, tripoint::z, and zlevels.

◆ draw()

void map::draw ( const catacurses::window w,
const tripoint center 
)

Draw a visible part of the map into w.

This method uses g->u.posx()/posy() for visibility calculations, so it can not be used for anything but the player's viewport. Likewise, only g->m and maps with equivalent coordinates can be used, as other maps would have coordinate systems incompatible with g->u.posx()

Parameters
wWindow we are drawing in
centerThe coordinate of the center of the viewport, this can be different from the player coordinate.

Definition at line 5700 of file map.cpp.

5701{
5702 // We only need to draw anything if we're not in tiles mode.
5703 if( is_draw_tiles_mode() ) {
5704 return;
5705 }
5706
5707 g->reset_light_level();
5708
5711
5712 const auto &visibility_cache = get_cache_ref( center.z ).visibility_cache;
5713
5714 int wnd_h = getmaxy( w );
5715 int wnd_w = getmaxx( w );
5716 const tripoint offs = center - tripoint( wnd_w / 2, wnd_h / 2, 0 );
5717
5718 // Map memory should be at least the size of the view range
5719 // so that new tiles can be memorized, and at least the size of the terminal
5720 // since displayed area may be bigger than view range.
5721 const point min_mm_reg = point(
5722 std::min( 0, offs.x ),
5723 std::min( 0, offs.y )
5724 );
5725 const point max_mm_reg = point(
5726 std::max( MAPSIZE_X, offs.x + wnd_w ),
5727 std::max( MAPSIZE_Y, offs.y + wnd_h )
5728 );
5729 g->u.prepare_map_memory_region(
5730 g->m.getabs( tripoint( min_mm_reg, center.z ) ),
5731 g->m.getabs( tripoint( max_mm_reg, center.z ) )
5732 );
5733
5734 const auto draw_background = [&]( const tripoint & p ) {
5735 int sym = ' ';
5736 nc_color col = c_black;
5737 if( has_memory_at( p ) ) {
5738 sym = get_memory_at( p );
5739 col = c_brown;
5740 }
5741 wputch( w, col, sym );
5742 };
5743
5744 const auto draw_vision_effect = [&]( const visibility_type vis ) -> bool {
5745 int sym = '#';
5746 nc_color col;
5747 switch( vis )
5748 {
5749 case VIS_LIT:
5750 // can only tell that this square is bright
5751 col = c_light_gray;
5752 break;
5753 case VIS_BOOMER:
5754 col = c_pink;
5755 break;
5756 case VIS_BOOMER_DARK:
5757 col = c_magenta;
5758 break;
5759 default:
5760 return false;
5761 }
5762 wputch( w, col, sym );
5763 return true;
5764 };
5765
5766 drawsq_params params = drawsq_params().memorize( true );
5767 for( int wy = 0; wy < wnd_h; wy++ ) {
5768 for( int wx = 0; wx < wnd_w; wx++ ) {
5769 wmove( w, point( wx, wy ) );
5770 const tripoint p = offs + tripoint( wx, wy, 0 );
5771 if( !inbounds( p ) ) {
5772 draw_background( p );
5773 continue;
5774 }
5775
5776 const lit_level lighting = visibility_cache[p.x][p.y];
5777 const visibility_type vis = get_visibility( lighting, cache );
5778
5779 if( draw_vision_effect( vis ) ) {
5780 continue;
5781 }
5782
5783 if( vis == VIS_HIDDEN || vis == VIS_DARK ) {
5784 draw_background( p );
5785 continue;
5786 }
5787
5788 const maptile curr_maptile = maptile_at_internal( p );
5789 params
5790 .low_light( lighting == lit_level::LOW )
5791 .bright_light( lighting == lit_level::BRIGHT );
5792 if( draw_maptile( w, p, curr_maptile, params ) ) {
5793 continue;
5794 }
5795 const maptile tile_below = maptile_at_internal( p - tripoint_above );
5796 draw_from_above( w, tripoint( p.xy(), p.z - 1 ), tile_below, params );
5797 }
5798 }
5799
5800 // Memorize off-screen tiles
5801 half_open_rectangle<point> display( offs.xy(), offs.xy() + point( wnd_w, wnd_h ) );
5802 drawsq_params mm_params = drawsq_params().memorize( true ).output( false );
5803 for( int y = 0; y < MAPSIZE_Y; y++ ) {
5804 for( int x = 0; x < MAPSIZE_X; x++ ) {
5805 const tripoint p( x, y, center.z );
5806 if( display.contains( p.xy() ) ) {
5807 // Have been memorized during display loop
5808 continue;
5809 }
5810
5811 const lit_level lighting = visibility_cache[p.x][p.y];
5812 const visibility_type vis = get_visibility( lighting, cache );
5813
5814 if( vis != VIS_CLEAR ) {
5815 continue;
5816 }
5817
5818 const maptile curr_maptile = maptile_at_internal( p );
5819 mm_params
5820 .low_light( lighting == lit_level::LOW )
5821 .bright_light( lighting == lit_level::BRIGHT );
5822
5823 draw_maptile( w, p, curr_maptile, mm_params );
5824 }
5825 }
5826}
bool draw_maptile(const catacurses::window &w, const tripoint &p, const maptile &tile, const drawsq_params &params) const
Internal version of the drawsq.
Definition: map.cpp:5865
visibility_type get_visibility(lit_level ll, const visibility_variables &cache) const
Definition: map.cpp:5650
void draw_from_above(const catacurses::window &w, const tripoint &p, const maptile &tile, const drawsq_params &params) const
Draws the tile as seen from above.
Definition: map.cpp:6056
const visibility_variables & get_visibility_variables_cache() const
Definition: map.cpp:5645
void update_visibility_cache(int zlev)
Definition: map.cpp:5596
maptile maptile_at_internal(const tripoint &p) const
Definition: map.cpp:219
#define c_light_gray
Definition: color.h:19
#define c_black
Definition: color.h:17
#define c_magenta
Definition: color.h:25
#define c_brown
Definition: color.h:26
#define c_pink
Definition: color.h:31
visibility_type
Definition: enums.h:57
@ VIS_CLEAR
Definition: enums.h:59
@ VIS_BOOMER
Definition: enums.h:61
@ VIS_DARK
Definition: enums.h:62
@ VIS_BOOMER_DARK
Definition: enums.h:63
@ VIS_HIDDEN
Definition: enums.h:58
@ VIS_LIT
Definition: enums.h:60
lit_level
Definition: lightmap.h:43
static bool has_memory_at(const tripoint &p)
Definition: map.cpp:5683
static int get_memory_at(const tripoint &p)
Definition: map.cpp:5692
int getmaxx(const window &win)
Definition: ncurses_def.cpp:58
int getmaxy(const window &win)
Definition: ncurses_def.cpp:63
void wmove(const window &win, const point &p)
Definition: ncurses_def.cpp:98
static tripoint_abs_omt display(const tripoint_abs_omt &orig, const draw_data_t &data=draw_data_t())
bool is_draw_tiles_mode()
Check whether we're in tile drawing mode.
Definition: output.cpp:2029
void wputch(const catacurses::window &w, nc_color FG, int ch)
Definition: output.cpp:470
static constexpr tripoint tripoint_above
Definition: point.h:294
Draw parameters used by map::drawsq() and similar methods.
Definition: map.h:180
constexpr drawsq_params & bright_light(bool v)
Whether tile is in bright light.
Definition: map.h:240
constexpr drawsq_params & output(bool v)
HACK: Whether the tile should be printed.
Definition: map.h:269
constexpr drawsq_params & memorize(bool v)
Whether the tile should be memorized.
Definition: map.h:254
constexpr drawsq_params & low_light(bool v)
Whether tile is low light, and should be drawn with muted color.
Definition: map.h:226
lit_level visibility_cache[MAPSIZE_X][MAPSIZE_Y]
Definition: map.h:355
A wrapper for a submap point.
Definition: submap.h:267

References BRIGHT, drawsq_params::bright_light(), c_black, c_brown, c_light_gray, c_magenta, c_pink, center, overmap_ui::display(), draw_from_above(), draw_maptile(), g, get_cache_ref(), get_memory_at(), get_visibility(), get_visibility_variables_cache(), catacurses::getmaxx(), catacurses::getmaxy(), has_memory_at(), inbounds(), is_draw_tiles_mode(), LOW, drawsq_params::low_light(), MAPSIZE_X, MAPSIZE_Y, maptile_at_internal(), drawsq_params::memorize(), drawsq_params::output(), tripoint_above, update_visibility_cache(), VIS_BOOMER, VIS_BOOMER_DARK, VIS_CLEAR, VIS_DARK, VIS_HIDDEN, VIS_LIT, level_cache::visibility_cache, catacurses::wmove(), wputch(), tripoint::x, tripoint::xy(), tripoint::y, and tripoint::z.

Referenced by advanced_inventory::draw_minimap(), and game::draw_ter().

◆ draw_anthill()

void map::draw_anthill ( mapgendata dat)
protected

Definition at line 5029 of file mapgen.cpp.

5030{
5031 const oter_id &terrain_type = dat.terrain_type();
5032 if( terrain_type == "anthill" || terrain_type == "acid_anthill" ) {
5033 for( int i = 0; i < SEEX * 2; i++ ) {
5034 for( int j = 0; j < SEEY * 2; j++ ) {
5035 if( i < 8 || j < 8 || i > SEEX * 2 - 9 || j > SEEY * 2 - 9 ) {
5036 ter_set( point( i, j ), dat.groundcover() );
5037 } else if( ( i == 11 || i == 12 ) && ( j == 11 || j == 12 ) ) {
5038 ter_set( point( i, j ), t_slope_down );
5039 } else {
5040 ter_set( point( i, j ), t_dirtmound );
5041 }
5042 }
5043 }
5044 }
5045}
const oter_id & terrain_type() const
Definition: mapgendata.h:87
ter_id groundcover()
Definition: mapgendata.cpp:141
ter_id t_slope_down
Definition: mapdata.cpp:718
ter_id t_dirtmound
Definition: mapdata.cpp:625

References mapgendata::groundcover(), SEEX, SEEY, t_dirtmound, t_slope_down, ter_set(), and mapgendata::terrain_type().

Referenced by draw_map().

◆ draw_circle_furn()

void map::draw_circle_furn ( const furn_id type,
const point p,
int  rad 
)

Definition at line 8439 of file map.cpp.

8440{
8441 draw_circle( [this, type]( const point & q ) {
8442 this->furn_set( q, type );
8443 }, p, rad );
8444}
void draw_circle(std::function< void(const point &)>set, const rl_vec2d &p, double rad)

References draw_circle(), furn_set(), and type.

Referenced by circle_furn().

◆ draw_circle_ter() [1/2]

void map::draw_circle_ter ( const ter_id type,
const point p,
int  rad 
)

Definition at line 8432 of file map.cpp.

8433{
8434 draw_circle( [this, type]( const point & q ) {
8435 this->ter_set( q, type );
8436 }, p, rad );
8437}

References draw_circle(), ter_set(), and type.

◆ draw_circle_ter() [2/2]

void map::draw_circle_ter ( const ter_id type,
const rl_vec2d p,
double  rad 
)

Definition at line 8425 of file map.cpp.

8426{
8427 draw_circle( [this, type]( const point & q ) {
8428 this->ter_set( q, type );
8429 }, p, rad );
8430}

References draw_circle(), ter_set(), and type.

Referenced by circle().

◆ draw_connections()

void map::draw_connections ( mapgendata dat)
protected

Definition at line 5239 of file mapgen.cpp.

5240{
5241 const oter_id &terrain_type = dat.terrain_type();
5242 if( is_ot_match( "subway", terrain_type,
5243 ot_match_type::type ) ) { // FUUUUU it's IF ELIF ELIF ELIF's mini-me =[
5244 if( is_ot_match( "sewer", dat.north(), ot_match_type::type ) &&
5245 !connects_to( terrain_type, 0 ) ) {
5246 if( connects_to( dat.north(), 2 ) ) {
5247 for( int i = SEEX - 2; i < SEEX + 2; i++ ) {
5248 for( int j = 0; j < SEEY; j++ ) {
5249 ter_set( point( i, j ), t_sewage );
5250 }
5251 }
5252 } else {
5253 for( int j = 0; j < 3; j++ ) {
5254 ter_set( point( SEEX, j ), t_rock_floor );
5255 ter_set( point( SEEX - 1, j ), t_rock_floor );
5256 }
5257 ter_set( point( SEEX, 3 ), t_door_metal_c );
5258 ter_set( point( SEEX - 1, 3 ), t_door_metal_c );
5259 }
5260 }
5261 if( is_ot_match( "sewer", dat.east(), ot_match_type::type ) &&
5262 !connects_to( terrain_type, 1 ) ) {
5263 if( connects_to( dat.east(), 3 ) ) {
5264 for( int i = SEEX; i < SEEX * 2; i++ ) {
5265 for( int j = SEEY - 2; j < SEEY + 2; j++ ) {
5266 ter_set( point( i, j ), t_sewage );
5267 }
5268 }
5269 } else {
5270 for( int i = SEEX * 2 - 3; i < SEEX * 2; i++ ) {
5271 ter_set( point( i, SEEY ), t_rock_floor );
5272 ter_set( point( i, SEEY - 1 ), t_rock_floor );
5273 }
5274 ter_set( point( SEEX * 2 - 4, SEEY ), t_door_metal_c );
5275 ter_set( point( SEEX * 2 - 4, SEEY - 1 ), t_door_metal_c );
5276 }
5277 }
5278 if( is_ot_match( "sewer", dat.south(), ot_match_type::type ) &&
5279 !connects_to( terrain_type, 2 ) ) {
5280 if( connects_to( dat.south(), 0 ) ) {
5281 for( int i = SEEX - 2; i < SEEX + 2; i++ ) {
5282 for( int j = SEEY; j < SEEY * 2; j++ ) {
5283 ter_set( point( i, j ), t_sewage );
5284 }
5285 }
5286 } else {
5287 for( int j = SEEY * 2 - 3; j < SEEY * 2; j++ ) {
5288 ter_set( point( SEEX, j ), t_rock_floor );
5289 ter_set( point( SEEX - 1, j ), t_rock_floor );
5290 }
5291 ter_set( point( SEEX, SEEY * 2 - 4 ), t_door_metal_c );
5292 ter_set( point( SEEX - 1, SEEY * 2 - 4 ), t_door_metal_c );
5293 }
5294 }
5295 if( is_ot_match( "sewer", dat.west(), ot_match_type::type ) &&
5296 !connects_to( terrain_type, 3 ) ) {
5297 if( connects_to( dat.west(), 1 ) ) {
5298 for( int i = 0; i < SEEX; i++ ) {
5299 for( int j = SEEY - 2; j < SEEY + 2; j++ ) {
5300 ter_set( point( i, j ), t_sewage );
5301 }
5302 }
5303 } else {
5304 for( int i = 0; i < 3; i++ ) {
5305 ter_set( point( i, SEEY ), t_rock_floor );
5306 ter_set( point( i, SEEY - 1 ), t_rock_floor );
5307 }
5308 ter_set( point( 3, SEEY ), t_door_metal_c );
5309 ter_set( point( 3, SEEY - 1 ), t_door_metal_c );
5310 }
5311 }
5312 } else if( is_ot_match( "sewer", terrain_type, ot_match_type::type ) ) {
5313 if( dat.above() == "road_nesw_manhole" ) {
5314 ter_set( point( rng( SEEX - 2, SEEX + 1 ), rng( SEEY - 2, SEEY + 1 ) ), t_ladder_up );
5315 }
5316 if( is_ot_match( "subway", dat.north(), ot_match_type::type ) &&
5317 !connects_to( terrain_type, 0 ) ) {
5318 for( int j = 0; j < SEEY - 3; j++ ) {
5319 ter_set( point( SEEX, j ), t_rock_floor );
5320 ter_set( point( SEEX - 1, j ), t_rock_floor );
5321 }
5322 ter_set( point( SEEX, SEEY - 3 ), t_door_metal_c );
5323 ter_set( point( SEEX - 1, SEEY - 3 ), t_door_metal_c );
5324 }
5325 if( is_ot_match( "subway", dat.east(), ot_match_type::type ) &&
5326 !connects_to( terrain_type, 1 ) ) {
5327 for( int i = SEEX + 3; i < SEEX * 2; i++ ) {
5328 ter_set( point( i, SEEY ), t_rock_floor );
5329 ter_set( point( i, SEEY - 1 ), t_rock_floor );
5330 }
5331 ter_set( point( SEEX + 2, SEEY ), t_door_metal_c );
5332 ter_set( point( SEEX + 2, SEEY - 1 ), t_door_metal_c );
5333 }
5334 if( is_ot_match( "subway", dat.south(), ot_match_type::type ) &&
5335 !connects_to( terrain_type, 2 ) ) {
5336 for( int j = SEEY + 3; j < SEEY * 2; j++ ) {
5337 ter_set( point( SEEX, j ), t_rock_floor );
5338 ter_set( point( SEEX - 1, j ), t_rock_floor );
5339 }
5340 ter_set( point( SEEX, SEEY + 2 ), t_door_metal_c );
5341 ter_set( point( SEEX - 1, SEEY + 2 ), t_door_metal_c );
5342 }
5343 if( is_ot_match( "subway", dat.west(), ot_match_type::type ) &&
5344 !connects_to( terrain_type, 3 ) ) {
5345 for( int i = 0; i < SEEX - 3; i++ ) {
5346 ter_set( point( i, SEEY ), t_rock_floor );
5347 ter_set( point( i, SEEY - 1 ), t_rock_floor );
5348 }
5349 ter_set( point( SEEX - 3, SEEY ), t_door_metal_c );
5350 ter_set( point( SEEX - 3, SEEY - 1 ), t_door_metal_c );
5351 }
5352 } else if( is_ot_match( "ants", terrain_type, ot_match_type::type ) ) {
5353 if( dat.above() == "anthill" ) {
5354 if( const auto p = random_point( *this, [this]( const tripoint & n ) {
5355 return ter( n ) == t_rock_floor;
5356 } ) ) {
5357 ter_set( *p, t_slope_up );
5358 }
5359 }
5360 }
5361
5362 // finally, any terrain with SIDEWALKS should contribute sidewalks to neighboring diagonal roads
5363 if( terrain_type->has_flag( has_sidewalk ) ) {
5364 for( int dir = 4; dir < 8; dir++ ) { // NE SE SW NW
5365 bool n_roads_nesw[4] = {};
5366 int n_num_dirs = terrain_type_to_nesw_array( oter_id( dat.t_nesw[dir] ), n_roads_nesw );
5367 // only handle diagonal neighbors
5368 if( n_num_dirs == 2 &&
5369 n_roads_nesw[( ( dir - 4 ) + 3 ) % 4] &&
5370 n_roads_nesw[( ( dir - 4 ) + 2 ) % 4] ) {
5371 // make drawing simpler by rotating the map back and forth
5372 rotate( 4 - ( dir - 4 ) );
5373 // draw a small triangle of sidewalk in the northeast corner
5374 for( int y = 0; y < 4; y++ ) {
5375 for( int x = SEEX * 2 - 4; x < SEEX * 2; x++ ) {
5376 if( x - y > SEEX * 2 - 4 ) {
5377 // TODO: more discriminating conditions
5378 if( ter( point( x, y ) ) == t_grass || ter( point( x, y ) ) == t_dirt ||
5379 ter( point( x, y ) ) == t_shrub ) {
5380 ter_set( point( x, y ), t_sidewalk );
5381 }
5382 }
5383 }
5384 }
5385 rotate( ( dir - 4 ) );
5386 }
5387 }
5388 }
5389
5391}
void rotate(int turns, bool setpos_safe=false)
Rotates this map, and all of its contents, by the specified multiple of 90 degrees.
Definition: mapgen.cpp:5802
const oter_id & above() const
Definition: mapgendata.h:131
const oter_id & north() const
Definition: mapgendata.h:107
const oter_id & west() const
Definition: mapgendata.h:116
const oter_id & south() const
Definition: mapgendata.h:113
oter_id t_nesw[8]
Definition: mapgendata.h:45
const oter_id & east() const
Definition: mapgendata.h:110
cata::optional< tripoint > random_point(const map &m, const std::function< bool(const tripoint &)> &predicate)
Same as other random_point with a range enclosing all valid points of the map.
ter_id t_grass
Definition: mapdata.cpp:628
ter_id t_sewage
Definition: mapdata.cpp:694
ter_id t_slope_up
Definition: mapdata.cpp:719
ter_id t_ladder_up
Definition: mapdata.cpp:718
ter_id t_shrub
Definition: mapdata.cpp:683
ter_id t_sidewalk
Definition: mapdata.cpp:630
ter_id t_door_metal_c
Definition: mapdata.cpp:662
bool connects_to(const oter_id &there, int dir)
Definition: mapgen.cpp:5904
void resolve_regional_terrain_and_furniture(const mapgendata &dat)
int terrain_type_to_nesw_array(oter_id terrain_type, bool array[4])
@ has_sidewalk
Definition: omdata.h:90
bool is_ot_match(const std::string &name, const oter_id &oter, const ot_match_type match_type)
Determine if the provided name is a match with the provided overmap terrain based on the specified ma...
Definition: overmap.cpp:568
bool has_flag(oter_flags flag) const
Definition: omdata.h:258

References mapgendata::above(), connects_to(), mapgendata::east(), oter_t::has_flag(), has_sidewalk, is_ot_match(), mapgendata::north(), oter_id, random_point(), resolve_regional_terrain_and_furniture(), rng(), rotate(), SEEX, SEEY, mapgendata::south(), t_dirt, t_door_metal_c, t_grass, t_ladder_up, mapgendata::t_nesw, t_rock_floor, t_sewage, t_shrub, t_sidewalk, t_slope_up, ter(), ter_set(), mapgendata::terrain_type(), terrain_type_to_nesw_array(), type, and mapgendata::west().

Referenced by draw_map().

◆ draw_fill_background() [1/3]

void map::draw_fill_background ( const ter_id type)

Definition at line 8354 of file map.cpp.

8355{
8356 // Need to explicitly set caches dirty - set_ter would do it before
8361
8362 // Fill each submap rather than each tile
8363 for( int gridx = 0; gridx < my_MAPSIZE; gridx++ ) {
8364 for( int gridy = 0; gridy < my_MAPSIZE; gridy++ ) {
8365 auto sm = get_submap_at_grid( {gridx, gridy} );
8366 sm->is_uniform = true;
8367 sm->set_all_ter( type );
8368 }
8369 }
8370}
void set_outside_cache_dirty(const int zlev)
Definition: map.h:447

References abs_sub, get_submap_at_grid(), my_MAPSIZE, set_outside_cache_dirty(), set_pathfinding_cache_dirty(), set_seen_cache_dirty(), set_transparency_cache_dirty(), coords::sm, type, and tripoint::z.

Referenced by fill_background(), mapgendata::fill_groundcover(), mapgen_function_json::generate(), and mapgen_forest().

◆ draw_fill_background() [2/3]

void map::draw_fill_background ( const weighted_int_list< ter_id > &  f)

Definition at line 8376 of file map.cpp.

8377{
8379}
void draw_square_ter(const ter_id &type, const point &p1, const point &p2)
Definition: map.cpp:8381

References draw_square_ter(), my_MAPSIZE, point_zero, SEEX, and SEEY.

◆ draw_fill_background() [3/3]

void map::draw_fill_background ( ter_id(*)()  f)

Definition at line 8372 of file map.cpp.

8373{
8375}

References draw_square_ter(), my_MAPSIZE, point_zero, SEEX, and SEEY.

◆ draw_from_above()

void map::draw_from_above ( const catacurses::window w,
const tripoint p,
const maptile tile,
const drawsq_params params 
) const
private

Draws the tile as seen from above.

Definition at line 6056 of file map.cpp.

6058{
6059 static const int AUTO_WALL_PLACEHOLDER = 2; // this should never appear as a real symbol!
6060
6061 nc_color tercol = c_dark_gray;
6062 int sym = ' ';
6063
6064 const ter_t &curr_ter = curr_tile.get_ter_t();
6065 const furn_t &curr_furn = curr_tile.get_furn_t();
6066 int part_below;
6067 const vehicle *veh;
6068 if( curr_furn.has_flag( TFLAG_SEEN_FROM_ABOVE ) ) {
6069 sym = curr_furn.symbol();
6070 tercol = curr_furn.color();
6071 } else if( curr_furn.movecost < 0 ) {
6072 sym = '.';
6073 tercol = curr_furn.color();
6074 } else if( ( veh = veh_at_internal( p, part_below ) ) != nullptr ) {
6075 const int roof = veh->roof_at_part( part_below );
6076 const int displayed_part = roof >= 0 ? roof : part_below;
6077 sym = special_symbol( veh->face.dir_symbol( veh->part_sym( displayed_part, true ) ) );
6078 tercol = ( roof >= 0 ||
6079 vpart_position( const_cast<vehicle &>( *veh ),
6080 part_below ).obstacle_at_part() ) ? c_light_gray : c_light_gray_cyan;
6081 } else if( curr_ter.has_flag( TFLAG_SEEN_FROM_ABOVE ) ) {
6082 if( curr_ter.has_flag( TFLAG_AUTO_WALL_SYMBOL ) ) {
6083 sym = AUTO_WALL_PLACEHOLDER;
6084 } else if( curr_ter.has_flag( TFLAG_RAMP ) ) {
6085 sym = '>';
6086 } else {
6087 sym = curr_ter.symbol();
6088 }
6089 tercol = curr_ter.color();
6090 } else if( curr_ter.movecost == 0 ) {
6091 sym = '.';
6092 tercol = curr_ter.color();
6093 } else if( !curr_ter.has_flag( TFLAG_NO_FLOOR ) ) {
6094 sym = '.';
6095 if( curr_ter.color() != c_cyan ) {
6096 // Need a special case here, it doesn't cyanize well
6097 tercol = cyan_background( curr_ter.color() );
6098 } else {
6099 tercol = c_black_cyan;
6100 }
6101 } else {
6102 sym = curr_ter.symbol();
6103 tercol = curr_ter.color();
6104 }
6105
6106 if( sym == AUTO_WALL_PLACEHOLDER ) {
6107 sym = determine_wall_corner( p );
6108 }
6109
6110 const auto u_vision = g->u.get_vision_modes();
6111 if( u_vision[BOOMERED] ) {
6112 tercol = c_magenta;
6113 } else if( u_vision[NV_GOGGLES] ) {
6114 tercol = params.bright_light() ? c_white : c_light_green;
6115 } else if( params.low_light() ) {
6116 tercol = c_dark_gray;
6117 } else if( u_vision[DARKNESS] ) {
6118 tercol = c_dark_gray;
6119 }
6120
6121 if( params.highlight() ) {
6122 tercol = invert_color( tercol );
6123 }
6124
6125 if( params.output() ) {
6126 wputch( w, tercol, sym );
6127 }
6128}
@ DARKNESS
Definition: character.h:93
@ NV_GOGGLES
Definition: character.h:89
@ BOOMERED
Definition: character.h:92
int determine_wall_corner(const tripoint &p) const
Definition: map.cpp:7843
vehicle * veh_at_internal(const tripoint &p, int &part_num)
Definition: map.cpp:1044
int dir_symbol(int sym) const
Definition: tileray.cpp:113
char part_sym(int p, bool exact=false) const
int roof_at_part(int p) const
Definition: vehicle.cpp:3012
tileray face
Definition: vehicle.h:1948
cata::optional< vpart_reference > obstacle_at_part() const
Returns the obstacle that exists at this point of the vehicle (if any).
Definition: vehicle.cpp:2438
nc_color invert_color(const nc_color &c)
Definition: color.cpp:503
nc_color cyan_background(const nc_color &c)
Definition: color.cpp:545
#define c_white
Definition: color.h:18
#define c_light_green
Definition: color.h:28
#define c_dark_gray
Definition: color.h:20
#define c_black_cyan
Definition: color.h:154
#define c_cyan
Definition: color.h:24
#define c_light_gray_cyan
Definition: color.h:156
@ TFLAG_AUTO_WALL_SYMBOL
Definition: mapdata.h:305
@ TFLAG_SEEN_FROM_ABOVE
Definition: mapdata.h:311
int special_symbol(int sym)
Definition: output.cpp:1095
constexpr drawsq_params & highlight(bool v)
Highlight the tile.
Definition: map.h:198
nc_color color() const
Definition: mapdata.cpp:555

References BOOMERED, drawsq_params::bright_light(), c_black_cyan, c_cyan, c_dark_gray, c_light_gray, c_light_gray_cyan, c_light_green, c_magenta, c_white, map_data_common_t::color(), cyan_background(), DARKNESS, determine_wall_corner(), tileray::dir_symbol(), vehicle::face, g, maptile::get_furn_t(), maptile::get_ter_t(), map_data_common_t::has_flag(), drawsq_params::highlight(), invert_color(), drawsq_params::low_light(), map_data_common_t::movecost, NV_GOGGLES, vpart_position::obstacle_at_part(), drawsq_params::output(), vehicle::part_sym(), vehicle::roof_at_part(), special_symbol(), map_data_common_t::symbol(), TFLAG_AUTO_WALL_SYMBOL, TFLAG_NO_FLOOR, TFLAG_RAMP, TFLAG_SEEN_FROM_ABOVE, veh_at_internal(), and wputch().

Referenced by draw(), and drawsq().

◆ draw_lab()

void map::draw_lab ( mapgendata dat)
protected

Definition at line 3519 of file mapgen.cpp.

3520{
3521 const oter_id &terrain_type = dat.terrain_type();
3522 // To distinguish between types of labs
3523 bool ice_lab = true;
3524 bool central_lab = false;
3525 bool tower_lab = false;
3526
3527 point p2;
3528
3529 int lw = 0;
3530 int rw = 0;
3531 int tw = 0;
3532 int bw = 0;
3533
3534 if( terrain_type == "lab" || terrain_type == "lab_stairs" || terrain_type == "lab_core" ||
3535 terrain_type == "ants_lab" || terrain_type == "ants_lab_stairs" ||
3536 terrain_type == "ice_lab" || terrain_type == "ice_lab_stairs" ||
3537 terrain_type == "ice_lab_core" ||
3538 terrain_type == "central_lab" || terrain_type == "central_lab_stairs" ||
3539 terrain_type == "central_lab_core" ||
3540 terrain_type == "tower_lab" || terrain_type == "tower_lab_stairs" ) {
3541
3542 ice_lab = is_ot_match( "ice_lab", terrain_type, ot_match_type::prefix );
3543 central_lab = is_ot_match( "central_lab", terrain_type, ot_match_type::prefix );
3544 tower_lab = is_ot_match( "tower_lab", terrain_type, ot_match_type::prefix );
3545
3546 if( ice_lab ) {
3547 int temperature = -20 + 30 * ( dat.zlevel() );
3549 set_temperature( p2 + point( SEEX, 0 ), temperature );
3550 set_temperature( p2 + point( 0, SEEY ), temperature );
3552 }
3553
3554 // Check for adjacent sewers; used below
3555 tw = 0;
3556 rw = 0;
3557 bw = 0;
3558 lw = 0;
3559 if( is_ot_match( "sewer", dat.north(), ot_match_type::type ) && connects_to( dat.north(), 2 ) ) {
3560 tw = SOUTH_EDGE + 1;
3561 }
3562 if( is_ot_match( "sewer", dat.east(), ot_match_type::type ) && connects_to( dat.east(), 3 ) ) {
3563 rw = EAST_EDGE + 1;
3564 }
3565 if( is_ot_match( "sewer", dat.south(), ot_match_type::type ) && connects_to( dat.south(), 0 ) ) {
3566 bw = SOUTH_EDGE + 1;
3567 }
3568 if( is_ot_match( "sewer", dat.west(), ot_match_type::type ) && connects_to( dat.west(), 1 ) ) {
3569 lw = EAST_EDGE + 1;
3570 }
3571 if( dat.zlevel() == 0 ) { // We're on ground level
3572 for( int i = 0; i < SEEX * 2; i++ ) {
3573 for( int j = 0; j < SEEY * 2; j++ ) {
3574 if( i <= 1 || i >= SEEX * 2 - 2 ||
3575 ( j > 1 && j < SEEY * 2 - 2 && ( i == SEEX - 2 || i == SEEX + 1 ) ) ) {
3576 ter_set( point( i, j ), t_concrete_wall );
3577 } else if( j <= 1 || j >= SEEY * 2 - 2 ) {
3578 ter_set( point( i, j ), t_concrete_wall );
3579 } else {
3580 ter_set( point( i, j ), t_floor );
3581 }
3582 }
3583 }
3584 ter_set( point( SEEX - 1, 0 ), t_door_metal_locked );
3585 ter_set( point( SEEX - 1, 1 ), t_floor );
3587 ter_set( point( SEEX, 1 ), t_floor );
3588 ter_set( point( SEEX - 2 + rng( 0, 1 ) * 3, 0 ), t_card_science );
3589 ter_set( point( SEEX - 2, SEEY ), t_door_metal_c );
3590 ter_set( point( SEEX + 1, SEEY ), t_door_metal_c );
3591 ter_set( point( SEEX - 2, SEEY - 1 ), t_door_metal_c );
3592 ter_set( point( SEEX + 1, SEEY - 1 ), t_door_metal_c );
3593 ter_set( point( SEEX - 1, SEEY * 2 - 3 ), t_stairs_down );
3594 ter_set( point( SEEX, SEEY * 2 - 3 ), t_stairs_down );
3595 science_room( this, point( 2, 2 ), point( SEEX - 3, SEEY * 2 - 3 ), dat.zlevel(), 1 );
3596 science_room( this, point( SEEX + 2, 2 ), point( SEEX * 2 - 3, SEEY * 2 - 3 ), dat.zlevel(), 3 );
3597
3598 place_spawns( GROUP_TURRET, 1, point( SEEX, 5 ), point( SEEX, 5 ), 1, true );
3599
3600 if( is_ot_match( "road", dat.east(), ot_match_type::type ) ) {
3601 rotate( 1 );
3602 } else if( is_ot_match( "road", dat.south(), ot_match_type::type ) ) {
3603 rotate( 2 );
3604 } else if( is_ot_match( "road", dat.west(), ot_match_type::type ) ) {
3605 rotate( 3 );
3606 }
3607 } else if( tw != 0 || rw != 0 || lw != 0 || bw != 0 ) { // Sewers!
3608 for( int i = 0; i < SEEX * 2; i++ ) {
3609 for( int j = 0; j < SEEY * 2; j++ ) {
3610 ter_set( point( i, j ), t_thconc_floor );
3611 if( ( ( i < lw || i > EAST_EDGE - rw ) && j > SEEY - 3 && j < SEEY + 2 ) ||
3612 ( ( j < tw || j > SOUTH_EDGE - bw ) && i > SEEX - 3 && i < SEEX + 2 ) ) {
3613 ter_set( point( i, j ), t_sewage );
3614 }
3615 if( ( i == 0 && is_ot_match( "lab", dat.east(), ot_match_type::contains ) ) || i == EAST_EDGE ) {
3616 if( ter( point( i, j ) ) == t_sewage ) {
3617 ter_set( point( i, j ), t_bars );
3618 } else if( j == SEEY - 1 || j == SEEY ) {
3619 ter_set( point( i, j ), t_door_metal_c );
3620 } else {
3621 ter_set( point( i, j ), t_concrete_wall );
3622 }
3623 } else if( ( j == 0 && is_ot_match( "lab", dat.north(), ot_match_type::contains ) ) ||
3624 j == SOUTH_EDGE ) {
3625 if( ter( point( i, j ) ) == t_sewage ) {
3626 ter_set( point( i, j ), t_bars );
3627 } else if( i == SEEX - 1 || i == SEEX ) {
3628 ter_set( point( i, j ), t_door_metal_c );
3629 } else {
3630 ter_set( point( i, j ), t_concrete_wall );
3631 }
3632 }
3633 }
3634 }
3635 } else { // We're below ground, and no sewers
3636 // Set up the boundaries of walls (connect to adjacent lab squares)
3637 tw = is_ot_match( "lab", dat.north(), ot_match_type::contains ) ? 0 : 2;
3638 rw = is_ot_match( "lab", dat.east(), ot_match_type::contains ) ? 1 : 2;
3639 bw = is_ot_match( "lab", dat.south(), ot_match_type::contains ) ? 1 : 2;
3640 lw = is_ot_match( "lab", dat.west(), ot_match_type::contains ) ? 0 : 2;
3641
3642 int boarders = 0;
3643 if( tw == 0 ) {
3644 boarders++;
3645 }
3646 if( rw == 1 ) {
3647 boarders++;
3648 }
3649 if( bw == 1 ) {
3650 boarders++;
3651 }
3652 if( lw == 0 ) {
3653 boarders++;
3654 }
3655
3656 const auto maybe_insert_stairs = [this]( const oter_id & terrain, const ter_id & t_stair_type ) {
3657 if( is_ot_match( "stairs", terrain, ot_match_type::contains ) ) {
3658 const auto predicate = [this]( const tripoint & p ) {
3659 return ter( p ) == t_thconc_floor && furn( p ) == f_null && tr_at( p ).is_null();
3660 };
3661 const auto range = points_in_rectangle( { 0, 0, abs_sub.z }, { SEEX * 2 - 2, SEEY * 2 - 2, abs_sub.z } );
3662
3663 if( const auto p = random_point( range, predicate ) ) {
3664 ter_set( *p, t_stair_type );
3665 }
3666 }
3667 };
3668
3669 //A lab area with only one entrance
3670 if( boarders == 1 ) {
3671 // If you remove the usage of "lab_1side" here, remove it from mapgen_factory::get_usages above as well.
3672 if( oter_mapgen.generate( dat, "lab_1side" ) ) {
3673 if( tw == 2 ) {
3674 rotate( 2 );
3675 }
3676 if( rw == 2 ) {
3677 rotate( 1 );
3678 }
3679 if( lw == 2 ) {
3680 rotate( 3 );
3681 }
3682 } else {
3683 debugmsg( "Error: Tried to generate 1-sided lab but no lab_1side json exists." );
3684 }
3685 maybe_insert_stairs( dat.above(), t_stairs_up );
3686 maybe_insert_stairs( terrain_type, t_stairs_down );
3687 } else {
3688 const int hardcoded_4side_map_weight = 1500; // weight of all hardcoded maps.
3689 // If you remove the usage of "lab_4side" here, remove it from mapgen_factory::get_usages above as well.
3690 if( oter_mapgen.generate( dat, "lab_4side", hardcoded_4side_map_weight ) ) {
3691 // If the map template hasn't handled borders, handle them in code.
3692 // Rotated maps cannot handle borders and have to be caught in code.
3693 // We determine if a border isn't handled by checking the east-facing
3694 // border space where the door normally is -- it should be a wall or door.
3695 tripoint east_border( 23, 11, abs_sub.z );
3696 if( !has_flag_ter( "WALL", east_border ) &&
3697 !has_flag_ter( "DOOR", east_border ) ) {
3698 // TODO: create a ter_reset function that does ter_set,
3699 // furn_set, and i_clear?
3700 ter_id lw_type = tower_lab ? t_reinforced_glass : t_concrete_wall;
3701 ter_id tw_type = tower_lab ? t_reinforced_glass : t_concrete_wall;
3702 ter_id rw_type = tower_lab && rw == 2 ? t_reinforced_glass :
3704 ter_id bw_type = tower_lab && bw == 2 ? t_reinforced_glass :
3706 for( int i = 0; i < SEEX * 2; i++ ) {
3707 ter_set( point( 23, i ), rw_type );
3708 furn_set( point( 23, i ), f_null );
3709 i_clear( tripoint( 23, i, get_abs_sub().z ) );
3710
3711 ter_set( point( i, 23 ), bw_type );
3712 furn_set( point( i, 23 ), f_null );
3713 i_clear( tripoint( i, 23, get_abs_sub().z ) );
3714
3715 if( lw == 2 ) {
3716 ter_set( point( 0, i ), lw_type );
3717 furn_set( point( 0, i ), f_null );
3718 i_clear( tripoint( 0, i, get_abs_sub().z ) );
3719 }
3720 if( tw == 2 ) {
3721 ter_set( point( i, 0 ), tw_type );
3722 furn_set( point( i, 0 ), f_null );
3723 i_clear( tripoint( i, 0, get_abs_sub().z ) );
3724 }
3725 }
3726 if( rw != 2 ) {
3727 ter_set( point( 23, 11 ), t_door_metal_c );
3728 ter_set( point( 23, 12 ), t_door_metal_c );
3729 }
3730 if( bw != 2 ) {
3731 ter_set( point( 11, 23 ), t_door_metal_c );
3732 ter_set( point( 12, 23 ), t_door_metal_c );
3733 }
3734 }
3735
3736 maybe_insert_stairs( dat.above(), t_stairs_up );
3737 maybe_insert_stairs( terrain_type, t_stairs_down );
3738 } else { // then no json maps for lab_4side were found
3739 switch( rng( 1, 3 ) ) {
3740 case 1:
3741 // Cross shaped
3742 for( int i = 0; i < SEEX * 2; i++ ) {
3743 for( int j = 0; j < SEEY * 2; j++ ) {
3744 if( ( i < lw || i > EAST_EDGE - rw ) ||
3745 ( ( j < SEEY - 1 || j > SEEY ) &&
3746 ( i == SEEX - 2 || i == SEEX + 1 ) ) ) {
3747 ter_set( point( i, j ), t_concrete_wall );
3748 } else if( ( j < tw || j > SOUTH_EDGE - bw ) ||
3749 ( ( i < SEEX - 1 || i > SEEX ) &&
3750 ( j == SEEY - 2 || j == SEEY + 1 ) ) ) {
3751 ter_set( point( i, j ), t_concrete_wall );
3752 } else {
3753 ter_set( point( i, j ), t_thconc_floor );
3754 }
3755 }
3756 }
3757 if( is_ot_match( "stairs", dat.above(), ot_match_type::contains ) ) {
3758 ter_set( point( rng( SEEX - 1, SEEX ), rng( SEEY - 1, SEEY ) ),
3759 t_stairs_up );
3760 }
3761 // Top left
3762 if( one_in( 2 ) ) {
3763 ter_set( point( SEEX - 2, int( SEEY / 2 ) ), t_door_glass_frosted_c );
3764 science_room( this, point( lw, tw ), point( SEEX - 3, SEEY - 3 ), dat.zlevel(), 1 );
3765 } else {
3767 science_room( this, point( lw, tw ), point( SEEX - 3, SEEY - 3 ), dat.zlevel(), 2 );
3768 }
3769 // Top right
3770 if( one_in( 2 ) ) {
3771 ter_set( point( SEEX + 1, int( SEEY / 2 ) ), t_door_glass_frosted_c );
3772 science_room( this, point( SEEX + 2, tw ), point( EAST_EDGE - rw, SEEY - 3 ),
3773 dat.zlevel(), 3 );
3774 } else {
3775 ter_set( point( SEEX + int( SEEX / 2 ), SEEY - 2 ), t_door_glass_frosted_c );
3776 science_room( this, point( SEEX + 2, tw ), point( EAST_EDGE - rw, SEEY - 3 ),
3777 dat.zlevel(), 2 );
3778 }
3779 // Bottom left
3780 if( one_in( 2 ) ) {
3782 science_room( this, point( lw, SEEY + 2 ), point( SEEX - 3, SOUTH_EDGE - bw ),
3783 dat.zlevel(), 0 );
3784 } else {
3785 ter_set( point( SEEX - 2, SEEY + int( SEEY / 2 ) ), t_door_glass_frosted_c );
3786 science_room( this, point( lw, SEEY + 2 ), point( SEEX - 3, SOUTH_EDGE - bw ),
3787 dat.zlevel(), 1 );
3788 }
3789 // Bottom right
3790 if( one_in( 2 ) ) {
3791 ter_set( point( SEEX + int( SEEX / 2 ), SEEY + 1 ), t_door_glass_frosted_c );
3792 science_room( this, point( SEEX + 2, SEEY + 2 ), point( EAST_EDGE - rw, SOUTH_EDGE - bw ),
3793 dat.zlevel(), 0 );
3794 } else {
3795 ter_set( point( SEEX + 1, SEEY + int( SEEY / 2 ) ), t_door_glass_frosted_c );
3796 science_room( this, point( SEEX + 2, SEEY + 2 ), point( EAST_EDGE - rw, SOUTH_EDGE - bw ),
3797 dat.zlevel(), 3 );
3798 }
3799 if( rw == 1 ) {
3802 }
3803 if( bw == 1 ) {
3806 }
3807 if( is_ot_match( "stairs", terrain_type, ot_match_type::contains ) ) { // Stairs going down
3808 std::vector<point> stair_points;
3809 if( tw != 0 ) {
3810 stair_points.push_back( point( SEEX - 1, 2 ) );
3811 stair_points.push_back( point( SEEX - 1, 2 ) );
3812 stair_points.push_back( point( SEEX, 2 ) );
3813 stair_points.push_back( point( SEEX, 2 ) );
3814 }
3815 if( rw != 1 ) {
3816 stair_points.push_back( point( SEEX * 2 - 3, SEEY - 1 ) );
3817 stair_points.push_back( point( SEEX * 2 - 3, SEEY - 1 ) );
3818 stair_points.push_back( point( SEEX * 2 - 3, SEEY ) );
3819 stair_points.push_back( point( SEEX * 2 - 3, SEEY ) );
3820 }
3821 if( bw != 1 ) {
3822 stair_points.push_back( point( SEEX - 1, SEEY * 2 - 3 ) );
3823 stair_points.push_back( point( SEEX - 1, SEEY * 2 - 3 ) );
3824 stair_points.push_back( point( SEEX, SEEY * 2 - 3 ) );
3825 stair_points.push_back( point( SEEX, SEEY * 2 - 3 ) );
3826 }
3827 if( lw != 0 ) {
3828 stair_points.push_back( point( 2, SEEY - 1 ) );
3829 stair_points.push_back( point( 2, SEEY - 1 ) );
3830 stair_points.push_back( point( 2, SEEY ) );
3831 stair_points.push_back( point( 2, SEEY ) );
3832 }
3833 stair_points.push_back( point( int( SEEX / 2 ), SEEY ) );
3834 stair_points.push_back( point( int( SEEX / 2 ), SEEY - 1 ) );
3835 stair_points.push_back( point( int( SEEX / 2 ) + SEEX, SEEY ) );
3836 stair_points.push_back( point( int( SEEX / 2 ) + SEEX, SEEY - 1 ) );
3837 stair_points.push_back( point( SEEX, int( SEEY / 2 ) ) );
3838 stair_points.push_back( point( SEEX + 2, int( SEEY / 2 ) ) );
3839 stair_points.push_back( point( SEEX, int( SEEY / 2 ) + SEEY ) );
3840 stair_points.push_back( point( SEEX + 2, int( SEEY / 2 ) + SEEY ) );
3841 const point p = random_entry( stair_points );
3842 ter_set( p, t_stairs_down );
3843 }
3844
3845 break;
3846
3847 case 2:
3848 // tic-tac-toe # layout
3849 for( int i = 0; i < SEEX * 2; i++ ) {
3850 for( int j = 0; j < SEEY * 2; j++ ) {
3851 if( i < lw || i > EAST_EDGE - rw || i == SEEX - 4 ||
3852 i == SEEX + 3 ) {
3853 ter_set( point( i, j ), t_concrete_wall );
3854 } else if( j < tw || j > SOUTH_EDGE - bw || j == SEEY - 4 ||
3855 j == SEEY + 3 ) {
3856 ter_set( point( i, j ), t_concrete_wall );
3857 } else {
3858 ter_set( point( i, j ), t_thconc_floor );
3859 }
3860 }
3861 }
3862 if( is_ot_match( "stairs", dat.above(), ot_match_type::contains ) ) {
3863 ter_set( point( SEEX - 1, SEEY - 1 ), t_stairs_up );
3864 ter_set( point( SEEX, SEEY - 1 ), t_stairs_up );
3865 ter_set( point( SEEX - 1, SEEY ), t_stairs_up );
3867 }
3868 ter_set( point( SEEX - rng( 0, 1 ), SEEY - 4 ), t_door_glass_frosted_c );
3869 ter_set( point( SEEX - rng( 0, 1 ), SEEY + 3 ), t_door_glass_frosted_c );
3870 ter_set( point( SEEX - 4, SEEY + rng( 0, 1 ) ), t_door_glass_frosted_c );
3871 ter_set( point( SEEX + 3, SEEY + rng( 0, 1 ) ), t_door_glass_frosted_c );
3872 ter_set( point( SEEX - 4, int( SEEY / 2 ) ), t_door_glass_frosted_c );
3873 ter_set( point( SEEX + 3, int( SEEY / 2 ) ), t_door_glass_frosted_c );
3876 ter_set( point( SEEX + int( SEEX / 2 ), SEEY - 4 ), t_door_glass_frosted_c );
3877 ter_set( point( SEEX + int( SEEX / 2 ), SEEY + 3 ), t_door_glass_frosted_c );
3878 ter_set( point( SEEX - 4, SEEY + int( SEEY / 2 ) ), t_door_glass_frosted_c );
3879 ter_set( point( SEEX + 3, SEEY + int( SEEY / 2 ) ), t_door_glass_frosted_c );
3880 science_room( this, point( lw, tw ), point( SEEX - 5, SEEY - 5 ), dat.zlevel(),
3881 rng( 1, 2 ) );
3882 science_room( this, point( SEEX - 3, tw ), point( SEEX + 2, SEEY - 5 ), dat.zlevel(), 2 );
3883 science_room( this, point( SEEX + 4, tw ), point( EAST_EDGE - rw, SEEY - 5 ),
3884 dat.zlevel(), rng( 2, 3 ) );
3885 science_room( this, point( lw, SEEY - 3 ), point( SEEX - 5, SEEY + 2 ), dat.zlevel(), 1 );
3886 science_room( this, point( SEEX + 4, SEEY - 3 ), point( EAST_EDGE - rw, SEEY + 2 ),
3887 dat.zlevel(), 3 );
3888 science_room( this, point( lw, SEEY + 4 ), point( SEEX - 5, SOUTH_EDGE - bw ),
3889 dat.zlevel(), rng( 0, 1 ) );
3890 science_room( this, point( SEEX - 3, SEEY + 4 ), point( SEEX + 2, SOUTH_EDGE - bw ),
3891 dat.zlevel(), 0 );
3892 science_room( this, point( SEEX + 4, SEEX + 4 ), point( EAST_EDGE - rw, SOUTH_EDGE - bw ),
3893 dat.zlevel(), 3 * rng( 0, 1 ) );
3894 if( rw == 1 ) {
3897 }
3898 if( bw == 1 ) {
3901 }
3902 if( is_ot_match( "stairs", terrain_type, ot_match_type::contains ) ) {
3903 ter_set( point( SEEX - 3 + 5 * rng( 0, 1 ), SEEY - 3 + 5 * rng( 0, 1 ) ),
3904 t_stairs_down );
3905 }
3906 break;
3907
3908 case 3:
3909 // Big room
3910 for( int i = 0; i < SEEX * 2; i++ ) {
3911 for( int j = 0; j < SEEY * 2; j++ ) {
3912 if( i < lw || i >= EAST_EDGE - rw ) {
3913 ter_set( point( i, j ), t_concrete_wall );
3914 } else if( j < tw || j >= SOUTH_EDGE - bw ) {
3915 ter_set( point( i, j ), t_concrete_wall );
3916 } else {
3917 ter_set( point( i, j ), t_thconc_floor );
3918 }
3919 }
3920 }
3921 science_room( this, point( lw, tw ), point( EAST_EDGE - rw, SOUTH_EDGE - bw ),
3922 dat.zlevel(), rng( 0, 3 ) );
3923
3924 if( rw == 1 ) {
3927 }
3928 if( bw == 1 ) {
3931 }
3932 maybe_insert_stairs( dat.above(), t_stairs_up );
3933 maybe_insert_stairs( terrain_type, t_stairs_down );
3934 break;
3935 }
3936 } // endif use_hardcoded_4side_map
3937 } // end 1 vs 4 sides
3938 } // end aboveground vs belowground
3939
3940 // Ants will totally wreck up the place
3941 if( is_ot_match( "ants", terrain_type, ot_match_type::contains ) ) {
3942 for( int i = 0; i < SEEX * 2; i++ ) {
3943 for( int j = 0; j < SEEY * 2; j++ ) {
3944 // Carve out a diamond area that covers 2 spaces on each edge.
3945 if( i + j > 10 && i + j < 36 && std::abs( i - j ) < 13 ) {
3946 // Doors and walls get sometimes destroyed:
3947 // 100% at the edge, usually in a central cross, occasionally elsewhere.
3948 if( ( has_flag_ter( "DOOR", point( i, j ) ) || has_flag_ter( "WALL", point( i, j ) ) ) ) {
3949 if( ( i == 0 || j == 0 || i == 23 || j == 23 ) ||
3950 ( !one_in( 3 ) && ( i == 11 || i == 12 || j == 11 || j == 12 ) ) ||
3951 one_in( 4 ) ) {
3952 // bash and usually remove the rubble.
3953 make_rubble( { i, j, abs_sub.z } );
3954 ter_set( point( i, j ), t_rock_floor );
3955 if( !one_in( 3 ) ) {
3956 furn_set( point( i, j ), f_null );
3957 }
3958 }
3959 // and then randomly destroy 5% of the remaining nonstairs.
3960 } else if( one_in( 20 ) &&
3961 !has_flag_ter( "GOES_DOWN", p2 ) &&
3962 !has_flag_ter( "GOES_UP", p2 ) ) {
3963 destroy( { i, j, abs_sub.z } );
3964 // bashed squares can create dirt & floors, but we want rock floors.
3965 if( t_dirt == ter( point( i, j ) ) || t_floor == ter( point( i, j ) ) ) {
3966 ter_set( point( i, j ), t_rock_floor );
3967 }
3968 }
3969 }
3970 }
3971 }
3972 }
3973
3974 // Slimes pretty much wreck up the place, too, but only underground
3975 tw = ( dat.north() == "slimepit" ? SEEY : 0 );
3976 rw = ( dat.east() == "slimepit" ? SEEX + 1 : 0 );
3977 bw = ( dat.south() == "slimepit" ? SEEY + 1 : 0 );
3978 lw = ( dat.west() == "slimepit" ? SEEX : 0 );
3979 if( tw != 0 || rw != 0 || bw != 0 || lw != 0 ) {
3980 for( int i = 0; i < SEEX * 2; i++ ) {
3981 for( int j = 0; j < SEEY * 2; j++ ) {
3982 if( ( ( j <= tw || i >= rw ) && i >= j && ( EAST_EDGE - i ) <= j ) ||
3983 ( ( j >= bw || i <= lw ) && i <= j && ( SOUTH_EDGE - j ) <= i ) ) {
3984 if( one_in( 5 ) ) {
3985 make_rubble( tripoint( i, j, abs_sub.z ), f_rubble_rock, true,
3986 t_slime );
3987 } else if( !one_in( 5 ) ) {
3988 ter_set( point( i, j ), t_slime );
3989 }
3990 }
3991 }
3992 }
3993 }
3994
3995 int light_odds = 0;
3996 // central labs are always fully lit, other labs have half chance of some lights.
3997 if( central_lab ) {
3998 light_odds = 1;
3999 } else if( one_in( 2 ) ) {
4000 // Create a spread of densities, from all possible lights on, to 1/3, ...
4001 // to ~1 per segment.
4002 light_odds = std::pow( rng( 1, 12 ), 1.6 );
4003 }
4004 if( light_odds > 0 ) {
4005 for( int i = 0; i < SEEX * 2; i++ ) {
4006 for( int j = 0; j < SEEY * 2; j++ ) {
4007 if( !( ( i * j ) % 2 || ( i + j ) % 4 ) && one_in( light_odds ) ) {
4008 if( t_thconc_floor == ter( point( i, j ) ) || t_strconc_floor == ter( point( i, j ) ) ) {
4010 }
4011 }
4012 }
4013 }
4014 }
4015
4016 if( tower_lab ) {
4018 }
4019
4020 // Lab special effects.
4021 if( one_in( 10 ) ) {
4022 switch( rng( 1, 7 ) ) {
4023 // full flooding/sewage
4024 case 1: {
4025 if( is_ot_match( "stairs", terrain_type, ot_match_type::contains ) ||
4026 is_ot_match( "ice", terrain_type, ot_match_type::contains ) ) {
4027 // don't flood if stairs because the floor below will not be flooded.
4028 // don't flood if ice lab because there's no mechanic for freezing
4029 // liquid floors.
4030 break;
4031 }
4032 auto fluid_type = one_in( 3 ) ? t_sewage : t_water_sh;
4033 for( int i = 0; i < EAST_EDGE; i++ ) {
4034 for( int j = 0; j < SOUTH_EDGE; j++ ) {
4035 // We spare some terrain to make it look better visually.
4036 if( !one_in( 10 ) && ( t_thconc_floor == ter( point( i, j ) ) ||
4037 t_strconc_floor == ter( point( i, j ) ) ||
4038 t_thconc_floor_olight == ter( point( i, j ) ) ) ) {
4039 ter_set( point( i, j ), fluid_type );
4040 } else if( has_flag_ter( "DOOR", point( i, j ) ) && !one_in( 3 ) ) {
4041 // We want the actual debris, but not the rubble marker or dirt.
4042 make_rubble( { i, j, abs_sub.z } );
4043 ter_set( point( i, j ), fluid_type );
4044 furn_set( point( i, j ), f_null );
4045 }
4046 }
4047 }
4048 break;
4049 }
4050 // minor flooding/sewage
4051 case 2: {
4052 if( is_ot_match( "stairs", terrain_type, ot_match_type::contains ) ||
4053 is_ot_match( "ice", terrain_type, ot_match_type::contains ) ) {
4054 // don't flood if stairs because the floor below will not be flooded.
4055 // don't flood if ice lab because there's no mechanic for freezing
4056 // liquid floors.
4057 break;
4058 }
4059 auto fluid_type = one_in( 3 ) ? t_sewage : t_water_sh;
4060 for( int i = 0; i < 2; ++i ) {
4061 draw_rough_circle( [this, fluid_type]( const point & p ) {
4062 if( t_thconc_floor == ter( p ) || t_strconc_floor == ter( p ) ||
4063 t_thconc_floor_olight == ter( p ) ) {
4064 ter_set( p, fluid_type );
4065 } else if( has_flag_ter( "DOOR", p ) ) {
4066 // We want the actual debris, but not the rubble marker or dirt.
4067 make_rubble( { p, abs_sub.z } );
4068 ter_set( p, fluid_type );
4069 furn_set( p, f_null );
4070 }
4071 }, point( rng( 1, SEEX * 2 - 2 ), rng( 1, SEEY * 2 - 2 ) ), rng( 3, 6 ) );
4072 }
4073 break;
4074 }
4075 // toxic gas leaks and smoke-filled rooms.
4076 case 3:
4077 case 4: {
4078 bool is_toxic = one_in( 3 );
4079 for( int i = 0; i < SEEX * 2; i++ ) {
4080 for( int j = 0; j < SEEY * 2; j++ ) {
4081 if( one_in( 200 ) && ( t_thconc_floor == ter( point( i, j ) ) ||
4082 t_strconc_floor == ter( point( i, j ) ) ) ) {
4083 if( is_toxic ) {
4084 add_field( {i, j, abs_sub.z}, fd_gas_vent, 1 );
4085 } else {
4086 add_field( {i, j, abs_sub.z}, fd_smoke_vent, 2 );
4087 }
4088 }
4089 }
4090 }
4091 break;
4092 }
4093 // portal with an artifact effect.
4094 case 5: {
4095 tripoint center( rng( 6, SEEX * 2 - 7 ), rng( 6, SEEY * 2 - 7 ), abs_sub.z );
4096 std::vector<artifact_natural_property> valid_props = {
4103 };
4104 draw_rough_circle( [this]( const point & p ) {
4105 if( has_flag_ter( "GOES_DOWN", p ) ||
4106 has_flag_ter( "GOES_UP", p ) ||
4107 has_flag_ter( "CONSOLE", p ) ) {
4108 return; // spare stairs and consoles.
4109 }
4110 make_rubble( {p, abs_sub.z } );
4111 ter_set( p, t_thconc_floor );
4112 }, center.xy(), 4 );
4113 furn_set( center.xy(), f_null );
4115 create_anomaly( center, random_entry( valid_props ), false );
4116 break;
4117 }
4118 // radioactive accident.
4119 case 6: {
4120 tripoint center( rng( 6, SEEX * 2 - 7 ), rng( 6, SEEY * 2 - 7 ), abs_sub.z );
4121 if( has_flag_ter( "WALL", center.xy() ) ) {
4122 // just skip it, we don't want to risk embedding radiation out of sight.
4123 break;
4124 }
4125 draw_rough_circle( [this]( const point & p ) {
4126 set_radiation( p, 10 );
4127 }, center.xy(), rng( 7, 12 ) );
4128 draw_circle( [this]( const point & p ) {
4129 set_radiation( p, 20 );
4130 }, center.xy(), rng( 5, 8 ) );
4131 draw_circle( [this]( const point & p ) {
4132 set_radiation( p, 30 );
4133 }, center.xy(), rng( 2, 4 ) );
4134 draw_circle( [this]( const point & p ) {
4135 set_radiation( p, 50 );
4136 }, center.xy(), 1 );
4137 draw_circle( [this]( const point & p ) {
4138 if( has_flag_ter( "GOES_DOWN", p ) ||
4139 has_flag_ter( "GOES_UP", p ) ||
4140 has_flag_ter( "CONSOLE", p ) ) {
4141 return; // spare stairs and consoles.
4142 }
4143 make_rubble( {p, abs_sub.z } );
4144 ter_set( p, t_thconc_floor );
4145 }, center.xy(), 1 );
4146
4148 center.xy() + point_west, 1, true );
4150 center.xy() + point_west, 1, true );
4151
4152 // damaged mininuke/plut thrown past edge of rubble so the player can see it.
4153 int marker_x = center.x - 2 + 4 * rng( 0, 1 );
4154 int marker_y = center.y + rng( -2, 2 );
4155 if( one_in( 4 ) ) {
4156 spawn_item(
4157 point( marker_x, marker_y ), "mininuke", 1, 1, calendar::start_of_cataclysm, rng( 2, 4 )
4158 );
4159 } else {
4160 item newliquid( "plut_slurry_dense", calendar::start_of_cataclysm );
4161 newliquid.charges = 1;
4162 add_item_or_charges( tripoint( marker_x, marker_y, get_abs_sub().z ),
4163 newliquid );
4164 }
4165 break;
4166 }
4167 // portal with fungal invasion
4168 case 7: {
4169 for( int i = 0; i < EAST_EDGE; i++ ) {
4170 for( int j = 0; j < SOUTH_EDGE; j++ ) {
4171 // Create a mostly spread fungal area throughout entire lab.
4172 if( !one_in( 5 ) && ( has_flag( "FLAT", point( i, j ) ) ) ) {
4173 ter_set( point( i, j ), t_fungus_floor_in );
4174 if( has_flag_furn( "ORGANIC", point( i, j ) ) ) {
4175 furn_set( point( i, j ), f_fungal_clump );
4176 }
4177 } else if( has_flag_ter( "DOOR", point( i, j ) ) && !one_in( 5 ) ) {
4178 ter_set( point( i, j ), t_fungus_floor_in );
4179 } else if( has_flag_ter( "WALL", point( i, j ) ) && one_in( 3 ) ) {
4180 ter_set( point( i, j ), t_fungus_wall );
4181 }
4182 }
4183 }
4184 tripoint center( rng( 6, SEEX * 2 - 7 ), rng( 6, SEEY * 2 - 7 ), abs_sub.z );
4185
4186 // Make a portal surrounded by more dense fungal stuff and a fungaloid.
4187 draw_rough_circle( [this]( const point & p ) {
4188 if( has_flag_ter( "GOES_DOWN", p ) ||
4189 has_flag_ter( "GOES_UP", p ) ||
4190 has_flag_ter( "CONSOLE", p ) ) {
4191 return; // spare stairs and consoles.
4192 }
4193 if( has_flag_ter( "WALL", p ) ) {
4194 ter_set( p, t_fungus_wall );
4195 } else {
4197 if( one_in( 3 ) ) {
4199 } else if( one_in( 10 ) ) {
4200 ter_set( p, t_marloss );
4201 }
4202 }
4203 }, center.xy(), 3 );
4205 furn_set( center.xy(), f_null );
4207 place_spawns( GROUP_FUNGI_FUNGALOID, 1, center.xy() + point( -2, -2 ),
4208 center.xy() + point( 2, 2 ), 1, true );
4209
4210 break;
4211 }
4212 }
4213 }
4214 } else if( terrain_type == "lab_finale" || terrain_type == "ice_lab_finale" ||
4215 terrain_type == "central_lab_finale" || terrain_type == "tower_lab_finale" ) {
4216
4217 ice_lab = is_ot_match( "ice_lab", terrain_type, ot_match_type::prefix );
4218 central_lab = is_ot_match( "central_lab", terrain_type, ot_match_type::prefix );
4219 tower_lab = is_ot_match( "tower_lab", terrain_type, ot_match_type::prefix );
4220
4221 if( ice_lab ) {
4222 int temperature = -20 + 30 * dat.zlevel();
4224 set_temperature( p2 + point( SEEX, 0 ), temperature );
4225 set_temperature( p2 + point( 0, SEEY ), temperature );
4227 }
4228
4229 tw = is_ot_match( "lab", dat.north(), ot_match_type::contains ) ? 0 : 2;
4230 rw = is_ot_match( "lab", dat.east(), ot_match_type::contains ) ? 1 : 2;
4231 bw = is_ot_match( "lab", dat.south(), ot_match_type::contains ) ? 1 : 2;
4232 lw = is_ot_match( "lab", dat.west(), ot_match_type::contains ) ? 0 : 2;
4233
4234 const int hardcoded_finale_map_weight = 500; // weight of all hardcoded maps.
4235 // If you remove the usage of "lab_finale_1level" here, remove it from mapgen_factory::get_usages above as well.
4236 if( oter_mapgen.generate( dat, "lab_finale_1level", hardcoded_finale_map_weight ) ) {
4237 // If the map template hasn't handled borders, handle them in code.
4238 // Rotated maps cannot handle borders and have to be caught in code.
4239 // We determine if a border isn't handled by checking the east-facing
4240 // border space where the door normally is -- it should be a wall or door.
4241 tripoint east_border( 23, 11, abs_sub.z );
4242 if( !has_flag_ter( "WALL", east_border ) && !has_flag_ter( "DOOR", east_border ) ) {
4243 // TODO: create a ter_reset function that does ter_set, furn_set, and i_clear?
4244 ter_id lw_type = tower_lab ? t_reinforced_glass : t_concrete_wall;
4245 ter_id tw_type = tower_lab ? t_reinforced_glass : t_concrete_wall;
4246 ter_id rw_type = tower_lab && rw == 2 ? t_reinforced_glass : t_concrete_wall;
4247 ter_id bw_type = tower_lab && bw == 2 ? t_reinforced_glass : t_concrete_wall;
4248 for( int i = 0; i < SEEX * 2; i++ ) {
4249 ter_set( point( 23, i ), rw_type );
4250 furn_set( point( 23, i ), f_null );
4251 i_clear( tripoint( 23, i, get_abs_sub().z ) );
4252
4253 ter_set( point( i, 23 ), bw_type );
4254 furn_set( point( i, 23 ), f_null );
4255 i_clear( tripoint( i, 23, get_abs_sub().z ) );
4256
4257 if( lw == 2 ) {
4258 ter_set( point( 0, i ), lw_type );
4259 furn_set( point( 0, i ), f_null );
4260 i_clear( tripoint( 0, i, get_abs_sub().z ) );
4261 }
4262 if( tw == 2 ) {
4263 ter_set( point( i, 0 ), tw_type );
4264 furn_set( point( i, 0 ), f_null );
4265 i_clear( tripoint( i, 0, get_abs_sub().z ) );
4266 }
4267 }
4268 if( rw != 2 ) {
4269 ter_set( point( 23, 11 ), t_door_metal_c );
4270 ter_set( point( 23, 12 ), t_door_metal_c );
4271 }
4272 if( bw != 2 ) {
4273 ter_set( point( 11, 23 ), t_door_metal_c );
4274 ter_set( point( 12, 23 ), t_door_metal_c );
4275 }
4276 }
4277 } else { // then no json maps for lab_finale_1level were found
4278 // Start by setting up a large, empty room.
4279 for( int i = 0; i < SEEX * 2; i++ ) {
4280 for( int j = 0; j < SEEY * 2; j++ ) {
4281 if( i < lw || i > EAST_EDGE - rw ) {
4282 ter_set( point( i, j ), t_concrete_wall );
4283 } else if( j < tw || j > SOUTH_EDGE - bw ) {
4284 ter_set( point( i, j ), t_concrete_wall );
4285 } else {
4286 ter_set( point( i, j ), t_thconc_floor );
4287 }
4288 }
4289 }
4290 if( rw == 1 ) {
4293 }
4294 if( bw == 1 ) {
4297 }
4298
4299 int loot_variant; //only used for weapons testing variant.
4300 computer *tmpcomp = nullptr;
4301 switch( rng( 1, 5 ) ) {
4302 // Weapons testing - twice as common because it has 4 variants.
4303 case 1:
4304 case 2:
4305 loot_variant = rng( 1, 100 ); //The variants have a 67/22/7/4 split.
4306 place_spawns( GROUP_ROBOT_SECUBOT, 1, point( 6, 6 ), point( 6, 6 ), 1, true );
4307 place_spawns( GROUP_ROBOT_SECUBOT, 1, point( SEEX * 2 - 7, 6 ),
4308 point( SEEX * 2 - 7, 6 ), 1, true );
4309 place_spawns( GROUP_ROBOT_SECUBOT, 1, point( 6, SEEY * 2 - 7 ),
4310 point( 6, SEEY * 2 - 7 ), 1, true );
4311 place_spawns( GROUP_ROBOT_SECUBOT, 1, point( SEEX * 2 - 7, SEEY * 2 - 7 ),
4312 point( SEEX * 2 - 7, SEEY * 2 - 7 ), 1, true );
4313 spawn_item( point( SEEX - 4, SEEY - 2 ), "id_science" );
4314 if( loot_variant <= 96 ) {
4315 mtrap_set( this, point( SEEX - 3, SEEY - 3 ), tr_dissector );
4316 mtrap_set( this, point( SEEX + 2, SEEY - 3 ), tr_dissector );
4317 mtrap_set( this, point( SEEX - 3, SEEY + 2 ), tr_dissector );
4318 mtrap_set( this, point( SEEX + 2, SEEY + 2 ), tr_dissector );
4319 line( this, t_reinforced_glass, point( SEEX + 1, SEEY + 1 ), point( SEEX - 2, SEEY + 1 ) );
4320 line( this, t_reinforced_glass, point( SEEX - 2, SEEY ), point( SEEX - 2, SEEY - 2 ) );
4321 line( this, t_reinforced_glass, point( SEEX - 1, SEEY - 2 ), point( SEEX + 1, SEEY - 2 ) );
4322 ter_set( point( SEEX + 1, SEEY - 1 ), t_reinforced_glass );
4324 furn_set( point( SEEX - 1, SEEY - 1 ), f_table );
4325 furn_set( point( SEEX, SEEY - 1 ), f_table );
4326 furn_set( point( SEEX - 1, SEEY ), f_table );
4327 furn_set( point( SEEX, SEEY ), f_table );
4328 if( loot_variant <= 67 ) {
4329 spawn_item( point( SEEX, SEEY - 1 ), "UPS_off" );
4330 spawn_item( point( SEEX, SEEY - 1 ), "heavy_battery_cell" );
4331 spawn_item( point( SEEX - 1, SEEY ), "v29" );
4332 spawn_item( point( SEEX - 1, SEEY ), "laser_rifle", dice( 1, 0 ) );
4333 spawn_item( point( SEEX, SEEY ), "plasma_gun" );
4334 spawn_item( point( SEEX, SEEY ), "plasma" );
4335 spawn_item( point( SEEX - 1, SEEY ), "recipe_atomic_battery" );
4336 spawn_item( point( SEEX + 1, SEEY ), "plut_cell", rng( 8, 20 ) );
4337 } else if( loot_variant < 89 ) {
4338 spawn_item( point( SEEX - 1, SEEY - 1 ), "mininuke", dice( 3, 6 ) );
4339 spawn_item( point( SEEX, SEEY - 1 ), "mininuke", dice( 3, 6 ) );
4340 spawn_item( point( SEEX - 1, SEEY ), "mininuke", dice( 3, 6 ) );
4341 spawn_item( point( SEEX, SEEY ), "mininuke", dice( 3, 6 ) );
4342 spawn_item( point( SEEX, SEEY ), "recipe_atomic_battery" );
4343 spawn_item( point( SEEX + 1, SEEY ), "plut_cell", rng( 8, 20 ) );
4344 } else { // loot_variant between 90 and 96.
4345 spawn_item( point( SEEX - 1, SEEY - 1 ), "rm13_armor" );
4346 spawn_item( point( SEEX, SEEY - 1 ), "plut_cell" );
4347 spawn_item( point( SEEX - 1, SEEY ), "plut_cell" );
4348 spawn_item( point( SEEX, SEEY ), "recipe_caseless" );
4349 }
4350 } else { // 4% of the lab ends will be this weapons testing end.
4351 mtrap_set( this, point( SEEX - 4, SEEY - 3 ), tr_dissector );
4352 mtrap_set( this, point( SEEX + 3, SEEY - 3 ), tr_dissector );
4353 mtrap_set( this, point( SEEX - 4, SEEY + 2 ), tr_dissector );
4354 mtrap_set( this, point( SEEX + 3, SEEY + 2 ), tr_dissector );
4355
4356 furn_set( point( SEEX - 2, SEEY - 1 ), f_rack );
4357 furn_set( point( SEEX - 1, SEEY - 1 ), f_rack );
4358 furn_set( point( SEEX, SEEY - 1 ), f_rack );
4359 furn_set( point( SEEX + 1, SEEY - 1 ), f_rack );
4360 furn_set( point( SEEX - 2, SEEY ), f_rack );
4361 furn_set( point( SEEX - 1, SEEY ), f_rack );
4362 furn_set( point( SEEX, SEEY ), f_rack );
4363 furn_set( point( SEEX + 1, SEEY ), f_rack );
4364 line( this, t_reinforced_door_glass_c, point( SEEX - 2, SEEY - 2 ),
4365 point( SEEX + 1, SEEY - 2 ) );
4366 line( this, t_reinforced_door_glass_c, point( SEEX - 2, SEEY + 1 ),
4367 point( SEEX + 1, SEEY + 1 ) );
4368 line( this, t_reinforced_glass, point( SEEX - 3, SEEY - 2 ), point( SEEX - 3, SEEY + 1 ) );
4369 line( this, t_reinforced_glass, point( SEEX + 2, SEEY - 2 ), point( SEEX + 2, SEEY + 1 ) );
4370 place_items( item_group_id( "ammo_rare" ), 96, point( SEEX - 2, SEEY - 1 ),
4371 point( SEEX + 1, SEEY - 1 ), false, calendar::start_of_cataclysm );
4372 place_items( item_group_id( "guns_rare" ), 96, point( SEEX - 2, SEEY ), point( SEEX + 1, SEEY ),
4373 false,
4375 spawn_item( point( SEEX + 1, SEEY ), "plut_cell", rng( 1, 10 ) );
4376 }
4377 break;
4378 // Netherworld access
4379 case 3: {
4380 bool monsters_end = false;
4381 if( !one_in( 4 ) ) { // Trapped netherworld monsters
4382 monsters_end = true;
4383 tw = rng( SEEY + 3, SEEY + 5 );
4384 bw = tw + 4;
4385 lw = rng( SEEX - 6, SEEX - 2 );
4386 rw = lw + 6;
4387 for( int i = lw; i <= rw; i++ ) {
4388 for( int j = tw; j <= bw; j++ ) {
4389 if( j == tw || j == bw ) {
4390 if( ( i - lw ) % 2 == 0 ) {
4391 ter_set( point( i, j ), t_concrete_wall );
4392 } else {
4393 ter_set( point( i, j ), t_reinforced_glass );
4394 }
4395 } else if( ( i - lw ) % 2 == 0 ) {
4396 ter_set( point( i, j ), t_concrete_wall );
4397 } else if( j == tw + 2 ) {
4398 ter_set( point( i, j ), t_concrete_wall );
4399 } else { // Empty space holds monsters!
4400 place_spawns( GROUP_NETHER, 1, point( i, j ), point( i, j ), 1, true );
4401 }
4402 }
4403 }
4404 }
4405
4406 spawn_item( point( SEEX - 1, 8 ), "id_science" );
4407 tmpcomp = add_computer( tripoint( SEEX, 8, abs_sub.z ),
4408 _( "Sub-prime contact console" ), 7 );
4409 if( monsters_end ) { //only add these options when there are monsters.
4410 tmpcomp->add_option( _( "Terminate Specimens" ), COMPACT_TERMINATE, 2 );
4411 tmpcomp->add_option( _( "Release Specimens" ), COMPACT_RELEASE, 3 );
4412 }
4413 tmpcomp->add_option( _( "Toggle Portal" ), COMPACT_PORTAL, 8 );
4414 tmpcomp->add_option( _( "Activate Resonance Cascade" ), COMPACT_CASCADE, 10 );
4415 tmpcomp->add_failure( COMPFAIL_MANHACKS );
4416 tmpcomp->add_failure( COMPFAIL_SECUBOTS );
4417 tmpcomp->set_access_denied_msg(
4418 _( "ERROR! Access denied! Unauthorized access will be met with lethal force!" ) );
4419 ter_set( point( SEEX - 2, 4 ), t_radio_tower );
4420 ter_set( point( SEEX + 1, 4 ), t_radio_tower );
4421 ter_set( point( SEEX - 2, 7 ), t_radio_tower );
4422 ter_set( point( SEEX + 1, 7 ), t_radio_tower );
4423 }
4424 break;
4425
4426 // Bionics
4427 case 4: {
4428 place_spawns( GROUP_ROBOT_SECUBOT, 1, point( 6, 6 ), point( 6, 6 ), 1, true );
4429 place_spawns( GROUP_ROBOT_SECUBOT, 1, point( SEEX * 2 - 7, 6 ),
4430 point( SEEX * 2 - 7, 6 ), 1, true );
4431 place_spawns( GROUP_ROBOT_SECUBOT, 1, point( 6, SEEY * 2 - 7 ),
4432 point( 6, SEEY * 2 - 7 ), 1, true );
4433 place_spawns( GROUP_ROBOT_SECUBOT, 1, point( SEEX * 2 - 7, SEEY * 2 - 7 ),
4434 point( SEEX * 2 - 7, SEEY * 2 - 7 ), 1, true );
4435 mtrap_set( this, point( SEEX - 2, SEEY - 2 ), tr_dissector );
4436 mtrap_set( this, point( SEEX + 1, SEEY - 2 ), tr_dissector );
4437 mtrap_set( this, point( SEEX - 2, SEEY + 1 ), tr_dissector );
4438 mtrap_set( this, point( SEEX + 1, SEEY + 1 ), tr_dissector );
4439 square_furn( this, f_counter, point( SEEX - 1, SEEY - 1 ), point( SEEX, SEEY ) );
4440 int item_count = 0;
4441 while( item_count < 5 ) {
4442 item_count += place_items( item_group_id( "bionics" ), 75, point( SEEX - 1, SEEY - 1 ),
4443 point( SEEX, SEEY ), false, calendar::start_of_cataclysm ).size();
4444 }
4445 line( this, t_reinforced_glass, point( SEEX - 2, SEEY - 2 ), point( SEEX + 1, SEEY - 2 ) );
4446 line( this, t_reinforced_glass, point( SEEX - 2, SEEY + 1 ), point( SEEX + 1, SEEY + 1 ) );
4447 line( this, t_reinforced_glass, point( SEEX - 2, SEEY - 1 ), point( SEEX - 2, SEEY ) );
4448 line( this, t_reinforced_glass, point( SEEX + 1, SEEY - 1 ), point( SEEX + 1, SEEY ) );
4449 spawn_item( point( SEEX - 4, SEEY - 3 ), "id_science" );
4450 ter_set( point( SEEX - 3, SEEY - 3 ), t_console );
4451 tmpcomp = add_computer( tripoint( SEEX - 3, SEEY - 3, abs_sub.z ),
4452 _( "Bionic access" ), 3 );
4453 tmpcomp->add_option( _( "Manifest" ), COMPACT_LIST_BIONICS, 0 );
4454 tmpcomp->add_option( _( "Open Chambers" ), COMPACT_RELEASE, 5 );
4455 tmpcomp->add_failure( COMPFAIL_MANHACKS );
4456 tmpcomp->add_failure( COMPFAIL_SECUBOTS );
4457 tmpcomp->set_access_denied_msg(
4458 _( "ERROR! Access denied! Unauthorized access will be met with lethal force!" ) );
4459 }
4460 break;
4461
4462 // CVD Forge
4463 case 5:
4464 place_spawns( GROUP_ROBOT_SECUBOT, 1, point( 6, 6 ), point( 6, 6 ), 1, true );
4465 place_spawns( GROUP_ROBOT_SECUBOT, 1, point( SEEX * 2 - 7, 6 ),
4466 point( SEEX * 2 - 7, 6 ), 1, true );
4467 place_spawns( GROUP_ROBOT_SECUBOT, 1, point( 6, SEEY * 2 - 7 ),
4468 point( 6, SEEY * 2 - 7 ), 1, true );
4469 place_spawns( GROUP_ROBOT_SECUBOT, 1, point( SEEX * 2 - 7, SEEY * 2 - 7 ),
4470 point( SEEX * 2 - 7, SEEY * 2 - 7 ), 1, true );
4471 line( this, t_cvdbody, point( SEEX - 2, SEEY - 2 ), point( SEEX - 2, SEEY + 1 ) );
4472 line( this, t_cvdbody, point( SEEX - 1, SEEY - 2 ), point( SEEX - 1, SEEY + 1 ) );
4473 line( this, t_cvdbody, point( SEEX, SEEY - 1 ), point( SEEX, SEEY + 1 ) );
4474 line( this, t_cvdbody, point( SEEX + 1, SEEY - 2 ), point( SEEX + 1, SEEY + 1 ) );
4475 ter_set( point( SEEX, SEEY - 2 ), t_cvdmachine );
4476 spawn_item( point( SEEX, SEEY - 3 ), "id_science" );
4477 break;
4478 }
4479 } // end use_hardcoded_lab_finale
4480
4481 // Handle stairs in the unlikely case they are needed.
4482
4483 const auto maybe_insert_stairs = [this]( const oter_id & terrain, const ter_id & t_stair_type ) {
4484 if( is_ot_match( "stairs", terrain, ot_match_type::contains ) ) {
4485 const auto predicate = [this]( const tripoint & p ) {
4486 return ter( p ) == t_thconc_floor && furn( p ) == f_null &&
4487 tr_at( p ).is_null();
4488 };
4489 const auto range = points_in_rectangle( { 0, 0, abs_sub.z },
4490 { SEEX * 2 - 2, SEEY * 2 - 2, abs_sub.z } );
4491 if( const auto p = random_point( range, predicate ) ) {
4492 ter_set( *p, t_stair_type );
4493 }
4494 }
4495 };
4496 maybe_insert_stairs( dat.above(), t_stairs_up );
4497 maybe_insert_stairs( terrain_type, t_stairs_down );
4498
4499 int light_odds = 0;
4500 // central labs are always fully lit, other labs have half chance of some lights.
4501 if( central_lab ) {
4502 light_odds = 1;
4503 } else if( one_in( 2 ) ) {
4504 light_odds = std::pow( rng( 1, 12 ), 1.6 );
4505 }
4506 if( light_odds > 0 ) {
4507 for( int i = 0; i < SEEX * 2; i++ ) {
4508 for( int j = 0; j < SEEY * 2; j++ ) {
4509 if( !( ( i * j ) % 2 || ( i + j ) % 4 ) && one_in( light_odds ) ) {
4510 if( t_thconc_floor == ter( point( i, j ) ) || t_strconc_floor == ter( point( i, j ) ) ) {
4512 }
4513 }
4514 }
4515 }
4516 }
4517 }
4518}
void set_access_denied_msg(const std::string &new_msg)
Definition: computer.cpp:97
void add_failure(const computer_failure &failure)
Definition: computer.cpp:87
void add_option(const computer_option &opt)
Definition: computer.cpp:76
void set_temperature(const tripoint &p, int temperature)
Definition: map.cpp:4069
computer * add_computer(const tripoint &p, const std::string &name, int security)
Definition: mapgen.cpp:5787
void i_clear(const tripoint &p)
Definition: map.cpp:4117
std::vector< item * > place_items(const item_group_id &loc, int chance, const tripoint &p1, const tripoint &p2, bool ongrass, const time_point &turn, int magazine=0, int ammo=0)
Place items from item group in the rectangle f - t.
Definition: mapgen.cpp:5517
void trap_set(const tripoint &p, const trap_id &type)
Definition: map.cpp:5177
bool generate(mapgendata &dat, const std::string &key, const int hardcoded_weight=0) const
Definition: mapgen.cpp:342
int zlevel() const
Definition: mapgendata.h:99
@ COMPACT_RELEASE
Definition: computer.h:42
@ COMPACT_TERMINATE
Definition: computer.h:59
@ COMPACT_PORTAL
Definition: computer.h:40
@ COMPACT_CASCADE
Definition: computer.h:19
@ COMPACT_LIST_BIONICS
Definition: computer.h:32
@ COMPFAIL_SECUBOTS
Definition: computer.h:77
@ COMPFAIL_MANHACKS
Definition: computer.h:74
void draw_rough_circle(std::function< void(const point &)>set, const point &p, int rad)
@ prefix
Definition: enums.h:79
@ contains
Definition: enums.h:83
field_type_id fd_gas_vent
Definition: field_type.cpp:350
field_type_id fd_smoke_vent
Definition: field_type.cpp:385
ter_id t_door_glass_frosted_c
Definition: mapdata.cpp:664
ter_id t_cvdmachine
Definition: mapdata.cpp:712
ter_id t_slime
Definition: mapdata.cpp:637
ter_id t_strconc_floor
Definition: mapdata.cpp:631
furn_id f_table
Definition: mapdata.cpp:1104
furn_id f_fungal_clump
Definition: mapdata.cpp:1116
ter_id t_cvdbody
Definition: mapdata.cpp:712
ter_id t_radio_tower
Definition: mapdata.cpp:703
ter_id t_fungus_floor_in
Definition: mapdata.cpp:690
furn_id f_counter
Definition: mapdata.cpp:1105
furn_id f_rack
Definition: mapdata.cpp:1107
ter_id t_fungus_wall
Definition: mapdata.cpp:690
ter_id t_reinforced_glass
Definition: mapdata.cpp:650
ter_id t_concrete_wall
Definition: mapdata.cpp:646
ter_id t_floor
Definition: mapdata.cpp:632
ter_id t_thconc_floor_olight
Definition: mapdata.cpp:631
ter_id t_bars
Definition: mapdata.cpp:653
ter_id t_thconc_floor
Definition: mapdata.cpp:631
furn_id f_rubble_rock
Definition: mapdata.cpp:1097
ter_id t_stairs_up
Definition: mapdata.cpp:718
ter_id t_stairs_down
Definition: mapdata.cpp:718
ter_id t_marloss
Definition: mapdata.cpp:690
ter_id t_door_metal_locked
Definition: mapdata.cpp:662
ter_id t_card_science
Definition: mapdata.cpp:722
ter_id t_reinforced_door_glass_c
Definition: mapdata.cpp:652
furn_id f_flower_fungal
Definition: mapdata.cpp:1116
void square_furn(map *m, const furn_id &type, const point &p1, const point &p2)
Definition: mapgen.cpp:6479
static const mongroup_id GROUP_ROBOT_SECUBOT("GROUP_ROBOT_SECUBOT")
static const mongroup_id GROUP_HAZMATBOT("GROUP_HAZMATBOT")
static const mongroup_id GROUP_NETHER("GROUP_NETHER")
static const mongroup_id GROUP_TURRET("GROUP_TURRET")
void line(map *m, const ter_id &type, const point &p1, const point &p2)
Definition: mapgen.cpp:6459
static void science_room(map *m, const point &p1, const point &p2, int z, int rotate)
Definition: mapgen.cpp:5953
const int SOUTH_EDGE
Definition: mapgen.cpp:2928
const int EAST_EDGE
Definition: mapgen.cpp:2929
static mapgen_factory oter_mapgen
Definition: mapgen.cpp:351
static const mongroup_id GROUP_FUNGI_FUNGALOID("GROUP_FUNGI_FUNGALOID")
static const mongroup_id GROUP_LAB("GROUP_LAB")
static const trap_str_id tr_portal("tr_portal")
static const trap_str_id tr_dissector("tr_dissector")
const time_point & start_of_cataclysm
Definition: calendar.cpp:33
quantity< int, temperature_in_millidegree_celsius_tag > temperature
std::pair< item, int > item_count
Definition: pickup.cpp:63
int dice(int number, int sides)
Definition: rng.cpp:85
V random_entry(const C &container, D default_value)
Returns a random entry in the container.
Definition: rng.h:88

References _, mapgendata::above(), abs_sub, add_computer(), computer::add_failure(), add_field(), add_item_or_charges(), computer::add_option(), ARTPROP_BREATHING, ARTPROP_CRACKLING, ARTPROP_GLOWING, ARTPROP_SCALED, ARTPROP_WARM, ARTPROP_WHISPERING, center, item::charges, COMPACT_CASCADE, COMPACT_LIST_BIONICS, COMPACT_PORTAL, COMPACT_RELEASE, COMPACT_TERMINATE, COMPFAIL_MANHACKS, COMPFAIL_SECUBOTS, connects_to(), contains, create_anomaly(), debugmsg, destroy(), dice(), draw_circle(), draw_rough_circle(), mapgendata::east(), EAST_EDGE, f_counter, f_flower_fungal, f_fungal_clump, f_null, f_rack, f_rubble_rock, f_table, fd_gas_vent, fd_smoke_vent, furn(), furn_set(), mapgen_factory::generate(), get_abs_sub(), GROUP_FUNGI_FUNGALOID, GROUP_HAZMATBOT, GROUP_LAB, GROUP_NETHER, GROUP_ROBOT_SECUBOT, GROUP_TURRET, has_flag(), has_flag_furn(), has_flag_ter(), i_clear(), trap::is_null(), is_ot_match(), line(), make_rubble(), mtrap_set(), mapgendata::north(), one_in(), oter_mapgen, place_items(), place_spawns(), point_west, point_zero, points_in_rectangle(), prefix, random_entry(), random_point(), rng(), rotate(), science_room(), SEEX, SEEY, computer::set_access_denied_msg(), set_radiation(), set_temperature(), mapgendata::south(), SOUTH_EDGE, spawn_item(), square_furn(), calendar::start_of_cataclysm, t_bars, t_card_science, t_concrete_wall, t_console, t_cvdbody, t_cvdmachine, t_dirt, t_door_glass_frosted_c, t_door_metal_c, t_door_metal_locked, t_floor, t_fungus_floor_in, t_fungus_wall, t_marloss, t_radio_tower, t_reinforced_door_glass_c, t_reinforced_glass, t_rock_floor, t_sewage, t_slime, t_stairs_down, t_stairs_up, t_strconc_floor, t_thconc_floor, t_thconc_floor_olight, t_water_sh, ter(), ter_set(), terrain, mapgendata::terrain_type(), tr_at(), tr_dissector, tr_portal, trap_set(), type, mapgendata::west(), tripoint::z, and mapgendata::zlevel().

Referenced by draw_map().

◆ draw_line_furn()

void map::draw_line_furn ( const furn_id type,
const point p1,
const point p2 
)

Definition at line 8347 of file map.cpp.

8348{
8349 draw_line( [this, type]( const point & p ) {
8350 this->furn_set( p, type );
8351 }, p1, p2 );
8352}
void draw_line(std::function< void(const point &)>set, const point &p1, const point &p2)

References draw_line(), furn_set(), and type.

Referenced by jmapgen_setmap::apply(), and line_furn().

◆ draw_line_ter()

void map::draw_line_ter ( const ter_id type,
const point p1,
const point p2 
)

Definition at line 8340 of file map.cpp.

8341{
8342 draw_line( [this, type]( const point & p ) {
8343 this->ter_set( p, type );
8344 }, p1, p2 );
8345}

References draw_line(), ter_set(), and type.

Referenced by jmapgen_setmap::apply(), and line().

◆ draw_map()

void map::draw_map ( mapgendata dat)
protected

Definition at line 2888 of file mapgen.cpp.

2889{
2890 const oter_id &terrain_type = dat.terrain_type();
2891 const std::string function_key = terrain_type->get_mapgen_id();
2892 bool found = true;
2893
2894 const bool generated = run_mapgen_func( function_key, dat );
2895
2896 if( !generated ) {
2897 if( is_ot_match( "slimepit", terrain_type, ot_match_type::prefix ) ||
2898 is_ot_match( "slime_pit", terrain_type, ot_match_type::prefix ) ) {
2899 draw_slimepit( dat );
2900 } else if( is_ot_match( "triffid", terrain_type, ot_match_type::prefix ) ) {
2901 draw_triffid( dat );
2902 } else if( is_ot_match( "office", terrain_type, ot_match_type::prefix ) ) {
2903 draw_office_tower( dat );
2904 } else if( is_ot_match( "temple", terrain_type, ot_match_type::prefix ) ) {
2905 draw_temple( dat );
2906 } else if( is_ot_match( "mine", terrain_type, ot_match_type::prefix ) ) {
2907 draw_mine( dat );
2908 } else if( is_ot_match( "anthill", terrain_type, ot_match_type::contains ) ) {
2909 draw_anthill( dat );
2910 } else if( is_ot_match( "lab", terrain_type, ot_match_type::contains ) ) {
2911 draw_lab( dat );
2912 } else {
2913 found = false;
2914 }
2915 }
2916
2917 if( !found ) {
2918 // not one of the hardcoded ones!
2919 // load from JSON???
2920 debugmsg( "Error: tried to generate map for omtype %s, \"%s\" (id_mapgen %s)",
2921 terrain_type.id().c_str(), terrain_type->get_name(), function_key.c_str() );
2922 fill_background( this, t_floor );
2923 }
2924
2925 draw_connections( dat );
2926}
void draw_office_tower(mapgendata &dat)
Definition: mapgen.cpp:2931
void draw_mine(mapgendata &dat)
Definition: mapgen.cpp:4766
void draw_triffid(mapgendata &dat)
Definition: mapgen.cpp:5091
void draw_anthill(mapgendata &dat)
Definition: mapgen.cpp:5029
void draw_slimepit(mapgendata &dat)
Definition: mapgen.cpp:5047
void draw_lab(mapgendata &dat)
Definition: mapgen.cpp:3519
void draw_connections(mapgendata &dat)
Definition: mapgen.cpp:5239
void draw_temple(mapgendata &dat)
Definition: mapgen.cpp:4520
void fill_background(map *m, const ter_id &type)
Definition: mapgen.cpp:6467
bool run_mapgen_func(const std::string &mapgen_id, mapgendata &dat)
Definition: mapgen.cpp:6691
std::string get_name() const
Definition: omdata.h:205
std::string get_mapgen_id() const
Definition: overmap.cpp:797

References string_id< T >::c_str(), contains, debugmsg, draw_anthill(), draw_connections(), draw_lab(), draw_mine(), draw_office_tower(), draw_slimepit(), draw_temple(), draw_triffid(), fill_background(), oter_t::get_mapgen_id(), oter_t::get_name(), int_id< T >::id(), is_ot_match(), prefix, run_mapgen_func(), t_floor, and mapgendata::terrain_type().

Referenced by generate().

◆ draw_maptile()

bool map::draw_maptile ( const catacurses::window w,
const tripoint p,
const maptile tile,
const drawsq_params params 
) const
private

Internal version of the drawsq.

Keeps a cached maptile for less re-getting. Returns false if it has drawn all it should, true if draw_from_above should be called after.

Definition at line 5865 of file map.cpp.

5867{
5868 drawsq_params param = params;
5869 nc_color tercol;
5870 const ter_t &curr_ter = curr_maptile.get_ter_t();
5871 const furn_t &curr_furn = curr_maptile.get_furn_t();
5872 const trap &curr_trap = curr_maptile.get_trap().obj();
5873 const field &curr_field = curr_maptile.get_field();
5874 int sym;
5875 bool hi = false;
5876 bool graf = false;
5877 bool draw_item_sym = false;
5878
5879 int terrain_sym;
5880 if( curr_ter.has_flag( TFLAG_AUTO_WALL_SYMBOL ) ) {
5881 terrain_sym = determine_wall_corner( p );
5882 } else {
5883 terrain_sym = curr_ter.symbol();
5884 }
5885
5886 if( curr_furn.id ) {
5887 sym = curr_furn.symbol();
5888 tercol = curr_furn.color();
5889 } else {
5890 sym = terrain_sym;
5891 tercol = curr_ter.color();
5892 }
5893 if( curr_ter.has_flag( TFLAG_SWIMMABLE ) && curr_ter.has_flag( TFLAG_DEEP_WATER ) &&
5894 !g->u.is_underwater() ) {
5895 param.show_items( false ); // Can only see underwater items if WE are underwater
5896 }
5897 // If there's a trap here, and we have sufficient perception, draw that instead
5898 if( curr_trap.can_see( p, g->u ) ) {
5899 tercol = curr_trap.color;
5900 if( curr_trap.sym == '%' ) {
5901 switch( rng( 1, 5 ) ) {
5902 case 1:
5903 sym = '*';
5904 break;
5905 case 2:
5906 sym = '0';
5907 break;
5908 case 3:
5909 sym = '8';
5910 break;
5911 case 4:
5912 sym = '&';
5913 break;
5914 case 5:
5915 sym = '+';
5916 break;
5917 }
5918 } else {
5919 sym = curr_trap.sym;
5920 }
5921 }
5922 if( curr_field.field_count() > 0 ) {
5923 const field_type_id &fid = curr_field.displayed_field_type();
5924 const field_entry *fe = curr_field.find_field( fid );
5925 const auto field_symbol = fid->get_symbol();
5926 if( field_symbol == "&" || fe == nullptr ) {
5927 // Do nothing, a '&' indicates invisible fields.
5928 } else if( field_symbol == "*" ) {
5929 // A random symbol.
5930 switch( rng( 1, 5 ) ) {
5931 case 1:
5932 sym = '*';
5933 break;
5934 case 2:
5935 sym = '0';
5936 break;
5937 case 3:
5938 sym = '8';
5939 break;
5940 case 4:
5941 sym = '&';
5942 break;
5943 case 5:
5944 sym = '+';
5945 break;
5946 }
5947 } else {
5948 // A field symbol '%' indicates the field should not hide
5949 // items/terrain. When the symbol is not '%' it will
5950 // hide items (the color is still inverted if there are items,
5951 // but the tile symbol is not changed).
5952 // draw_item_sym indicates that the item symbol should be used
5953 // even if sym is not '.'.
5954 // As we don't know at this stage if there are any items
5955 // (that are visible to the player!), we always set the symbol.
5956 // If there are items and the field does not hide them,
5957 // the code handling items will override it.
5958 draw_item_sym = ( field_symbol == "'%" );
5959 // If field display_priority is > 1, and the field is set to hide items,
5960 //draw the field as it obscures what's under it.
5961 if( ( field_symbol != "%" && fid.obj().priority > 1 ) || ( field_symbol != "%" &&
5962 sym == '.' ) ) {
5963 // default terrain '.' and
5964 // non-default field symbol -> field symbol overrides terrain
5965 sym = field_symbol[0];
5966 }
5967 tercol = fe->color();
5968 }
5969 }
5970
5971 // TODO: change the local variable sym to std::string and use it instead of this hack.
5972 // Currently this are different variables because terrain/... uses int as symbol type and
5973 // item now use string. Ideally they should all be strings.
5974 std::string item_sym;
5975
5976 // If there are items here, draw those instead
5977 if( param.show_items() && curr_maptile.get_item_count() > 0 && sees_some_items( p, g->u ) ) {
5978 // if there's furniture/terrain/trap/fields (sym!='.')
5979 // and we should not override it, then only highlight the square
5980 if( sym != '.' && sym != '%' && !draw_item_sym ) {
5981 hi = true;
5982 } else {
5983 // otherwise override with the symbol of the last item
5984 item_sym = curr_maptile.get_uppermost_item().symbol();
5985 if( !draw_item_sym ) {
5986 tercol = curr_maptile.get_uppermost_item().color();
5987 }
5988 if( curr_maptile.get_item_count() > 1 ) {
5989 param.highlight( !param.highlight() );
5990 }
5991 }
5992 }
5993
5994 int memory_sym = sym;
5995 int veh_part = 0;
5996 const vehicle *veh = veh_at_internal( p, veh_part );
5997 if( veh != nullptr ) {
5998 sym = special_symbol( veh->face.dir_symbol( veh->part_sym( veh_part ) ) );
5999 tercol = veh->part_color( veh_part );
6000 item_sym.clear(); // clear the item symbol so `sym` is used instead.
6001
6002 if( !veh->forward_velocity() && !veh->player_in_control( g->u ) ) {
6003 memory_sym = sym;
6004 }
6005 }
6006
6007 if( param.memorize() && check_and_set_seen_cache( p ) ) {
6008 g->u.memorize_symbol( getabs( p ), memory_sym );
6009 }
6010
6011 // If there's graffiti here, change background color
6012 if( curr_maptile.has_graffiti() ) {
6013 graf = true;
6014 }
6015
6016 const auto u_vision = g->u.get_vision_modes();
6017 if( u_vision[BOOMERED] ) {
6018 tercol = c_magenta;
6019 } else if( u_vision[NV_GOGGLES] ) {
6020 tercol = param.bright_light() ? c_white : c_light_green;
6021 } else if( param.low_light() ) {
6022 tercol = c_dark_gray;
6023 } else if( u_vision[DARKNESS] ) {
6024 tercol = c_dark_gray;
6025 }
6026
6027 if( param.highlight() ) {
6028 tercol = invert_color( tercol );
6029 } else if( hi ) {
6030 tercol = hilite( tercol );
6031 } else if( graf ) {
6032 tercol = red_background( tercol );
6033 }
6034
6035 if( item_sym.empty() && sym == ' ' ) {
6036 if( !zlevels || p.z <= -OVERMAP_DEPTH || !curr_ter.has_flag( TFLAG_NO_FLOOR ) ) {
6037 // Print filler symbol
6038 sym = ' ';
6039 tercol = c_black;
6040 } else {
6041 // Draw tile underneath this one instead
6042 return false;
6043 }
6044 }
6045
6046 if( params.output() ) {
6047 if( item_sym.empty() ) {
6048 wputch( w, tercol, sym );
6049 } else {
6050 wprintz( w, tercol, item_sym );
6051 }
6052 }
6053 return true;
6054}
nc_color color() const
Definition: field.cpp:94
field_entry * find_field(const field_type_id &field_type_to_find)
Returns a field entry corresponding to the field_type_id parameter passed in.
Definition: field.cpp:153
field_type_id displayed_field_type() const
Returns field type that should be drawn.
Definition: field.cpp:275
unsigned int field_count() const
Definition: field.cpp:246
bool check_and_set_seen_cache(const tripoint &p) const
Definition: map.h:491
bool sees_some_items(const tripoint &p, const Creature &who) const
Check if creature can see some items at p.
Definition: map.cpp:4725
nc_color part_color(int p, bool exact=false) const
bool player_in_control(const Character &p) const
Definition: vehicle.cpp:277
float forward_velocity() const
nc_color red_background(const nc_color &c)
Definition: color.cpp:515
nc_color hilite(const nc_color &c)
Definition: color.cpp:509
@ TFLAG_SWIMMABLE
Definition: mapdata.h:279
void wprintz(const catacurses::window &w, const nc_color &FG, const std::string &text)
Definition: output.cpp:2043
constexpr drawsq_params & show_items(bool v)
Whether to draw items on the tile.
Definition: map.h:212
int priority
Definition: field_type.h:176
std::string get_symbol(int level=0) const
Definition: field_type.h:195
furn_str_id id
Definition: mapdata.h:496
nc_color color
Definition: trap.h:93
int sym
Definition: trap.h:92

References BOOMERED, drawsq_params::bright_light(), c_black, c_dark_gray, c_light_green, c_magenta, c_white, trap::can_see(), check_and_set_seen_cache(), field_entry::color(), item::color(), map_data_common_t::color(), trap::color, DARKNESS, determine_wall_corner(), tileray::dir_symbol(), field::displayed_field_type(), vehicle::face, field::field_count(), field::find_field(), vehicle::forward_velocity(), g, maptile::get_field(), maptile::get_furn_t(), maptile::get_item_count(), field_type::get_symbol(), maptile::get_ter_t(), maptile::get_trap(), maptile::get_uppermost_item(), getabs(), map_data_common_t::has_flag(), maptile::has_graffiti(), drawsq_params::highlight(), hilite(), furn_t::id, invert_color(), drawsq_params::low_light(), drawsq_params::memorize(), NV_GOGGLES, int_id< T >::obj(), drawsq_params::output(), OVERMAP_DEPTH, vehicle::part_color(), vehicle::part_sym(), vehicle::player_in_control(), field_type::priority, red_background(), rng(), sees_some_items(), drawsq_params::show_items(), special_symbol(), trap::sym, item::symbol(), map_data_common_t::symbol(), TFLAG_AUTO_WALL_SYMBOL, TFLAG_DEEP_WATER, TFLAG_NO_FLOOR, TFLAG_SWIMMABLE, veh_at_internal(), wprintz(), wputch(), tripoint::z, and zlevels.

Referenced by draw(), and drawsq().

◆ draw_mine()

void map::draw_mine ( mapgendata dat)
protected

Definition at line 4766 of file mapgen.cpp.

4767{
4768 const oter_id &terrain_type = dat.terrain_type();
4769 if( terrain_type == "mine" || terrain_type == "mine_down" ) {
4770 if( is_ot_match( "mine", dat.north(), ot_match_type::prefix ) ) {
4771 dat.n_fac = ( one_in( 10 ) ? 0 : -2 );
4772 } else {
4773 dat.n_fac = 4;
4774 }
4775 if( is_ot_match( "mine", dat.east(), ot_match_type::prefix ) ) {
4776 dat.e_fac = ( one_in( 10 ) ? 0 : -2 );
4777 } else {
4778 dat.e_fac = 4;
4779 }
4780 if( is_ot_match( "mine", dat.south(), ot_match_type::prefix ) ) {
4781 dat.s_fac = ( one_in( 10 ) ? 0 : -2 );
4782 } else {
4783 dat.s_fac = 4;
4784 }
4785 if( is_ot_match( "mine", dat.west(), ot_match_type::prefix ) ) {
4786 dat.w_fac = ( one_in( 10 ) ? 0 : -2 );
4787 } else {
4788 dat.w_fac = 4;
4789 }
4790
4791 for( int i = 0; i < SEEX * 2; i++ ) {
4792 for( int j = 0; j < SEEY * 2; j++ ) {
4793 if( i >= dat.w_fac + rng( 0, 2 ) && i <= EAST_EDGE - dat.e_fac - rng( 0, 2 ) &&
4794 j >= dat.n_fac + rng( 0, 2 ) && j <= SOUTH_EDGE - dat.s_fac - rng( 0, 2 ) &&
4795 i + j >= 4 && ( SEEX * 2 - i ) + ( SEEY * 2 - j ) >= 6 ) {
4796 ter_set( point( i, j ), t_rock_floor );
4797 } else {
4798 ter_set( point( i, j ), t_rock );
4799 }
4800 }
4801 }
4802
4803 // Not an entrance; maybe some hazards!
4804 switch( rng( 0, 4 ) ) {
4805 case 0:
4806 break; // Nothing! Lucky!
4807
4808 case 1: {
4809 // Toxic gas
4810 point gas_vent_location( rng( 9, 14 ), rng( 9, 14 ) );
4811 ter_set( point( gas_vent_location ), t_rock );
4812 add_field( { gas_vent_location, abs_sub.z }, fd_gas_vent, 2 );
4813 }
4814 break;
4815
4816 case 2: {
4817 // Lava
4818 point start_location( rng( 6, SEEX ), rng( 6, SEEY ) );
4819 point end_location( rng( SEEX + 1, SEEX * 2 - 7 ), rng( SEEY + 1, SEEY * 2 - 7 ) );
4820 const int num = rng( 2, 4 );
4821 for( int i = 0; i < num; i++ ) {
4822 int lx1 = start_location.x + rng( -1, 1 );
4823 int lx2 = end_location.x + rng( -1, 1 );
4824 int ly1 = start_location.y + rng( -1, 1 );
4825 int ly2 = end_location.y + rng( -1, 1 );
4826 line( this, t_lava, point( lx1, ly1 ), point( lx2, ly2 ) );
4827 }
4828 }
4829 break;
4830
4831 case 3: {
4832 // Wrecked equipment
4833 point wreck_location( rng( 9, 14 ), rng( 9, 14 ) );
4834 for( int i = wreck_location.x - 3; i < wreck_location.x + 3; i++ ) {
4835 for( int j = wreck_location.y - 3; j < wreck_location.y + 3; j++ ) {
4836 if( !one_in( 4 ) ) {
4837 make_rubble( tripoint( i, j, abs_sub.z ), f_wreckage, true );
4838 }
4839 }
4840 }
4841 place_items( item_group_id( "wreckage" ), 70, wreck_location + point( -3, -3 ),
4842 wreck_location + point( 2, 2 ), false, calendar::start_of_cataclysm );
4843 }
4844 break;
4845
4846 case 4: {
4847 // Dead miners
4848 const int num_bodies = rng( 4, 8 );
4849 for( int i = 0; i < num_bodies; i++ ) {
4850 if( const auto body = random_point( *this, [this]( const tripoint & p ) {
4851 return move_cost( p ) == 2;
4852 } ) ) {
4853 add_item( *body, item::make_corpse() );
4854 place_items( item_group_id( "mine_equipment" ), 60, *body, *body,
4856 }
4857 }
4858 }
4859 break;
4860
4861 }
4862
4863 if( terrain_type == "mine_down" ) { // Don't forget to build a slope down!
4864 std::vector<direction> open;
4865 if( dat.n_fac == 4 ) {
4866 open.push_back( direction::NORTH );
4867 }
4868 if( dat.e_fac == 4 ) {
4869 open.push_back( direction::EAST );
4870 }
4871 if( dat.s_fac == 4 ) {
4872 open.push_back( direction::SOUTH );
4873 }
4874 if( dat.w_fac == 4 ) {
4875 open.push_back( direction::WEST );
4876 }
4877
4878 if( open.empty() ) { // We'll have to build it in the center
4879 int tries = 0;
4880 point p;
4881 bool okay = true;
4882 do {
4883 p.x = rng( SEEX - 6, SEEX + 1 );
4884 p.y = rng( SEEY - 6, SEEY + 1 );
4885 okay = true;
4886 for( int i = p.x; ( i <= p.x + 5 ) && okay; i++ ) {
4887 for( int j = p.y; ( j <= p.y + 5 ) && okay; j++ ) {
4888 if( ter( point( i, j ) ) != t_rock_floor ) {
4889 okay = false;
4890 }
4891 }
4892 }
4893 if( !okay ) {
4894 tries++;
4895 }
4896 } while( !okay && tries < 10 );
4897 if( tries == 10 ) { // Clear the area around the slope down
4898 square( this, t_rock_floor, p, p + point( 5, 5 ) );
4899 }
4900 // NOLINTNEXTLINE(cata-use-named-point-constants)
4901 square( this, t_slope_down, p + point( 1, 1 ), p + point( 2, 2 ) );
4902 } else { // We can build against a wall
4903 switch( random_entry( open ) ) {
4904 case direction::NORTH:
4905 square( this, t_rock_floor, point( SEEX - 3, 6 ), point( SEEX + 2, SEEY ) );
4906 line( this, t_slope_down, point( SEEX - 2, 6 ), point( SEEX + 1, 6 ) );
4907 break;
4908 case direction::EAST:
4909 square( this, t_rock_floor, point( SEEX + 1, SEEY - 3 ), point( SEEX * 2 - 7, SEEY + 2 ) );
4910 line( this, t_slope_down, point( SEEX * 2 - 7, SEEY - 2 ), point( SEEX * 2 - 7, SEEY + 1 ) );
4911 break;
4912 case direction::SOUTH:
4913 square( this, t_rock_floor, point( SEEX - 3, SEEY + 1 ), point( SEEX + 2, SEEY * 2 - 7 ) );
4914 line( this, t_slope_down, point( SEEX - 2, SEEY * 2 - 7 ), point( SEEX + 1, SEEY * 2 - 7 ) );
4915 break;
4916 case direction::WEST:
4917 square( this, t_rock_floor, point( 6, SEEY - 3 ), point( SEEX, SEEY + 2 ) );
4918 line( this, t_slope_down, point( 6, SEEY - 2 ), point( 6, SEEY + 1 ) );
4919 break;
4920 default:
4921 break;
4922 }
4923 }
4924 } // Done building a slope down
4925
4926 if( dat.above() == "mine_down" ) { // Don't forget to build a slope up!
4927 std::vector<direction> open;
4928 if( dat.n_fac == 6 && ter( point( SEEX, 6 ) ) != t_slope_down ) {
4929 open.push_back( direction::NORTH );
4930 }
4931 if( dat.e_fac == 6 && ter( point( SEEX * 2 - 7, SEEY ) ) != t_slope_down ) {
4932 open.push_back( direction::EAST );
4933 }
4934 if( dat.s_fac == 6 && ter( point( SEEX, SEEY * 2 - 7 ) ) != t_slope_down ) {
4935 open.push_back( direction::SOUTH );
4936 }
4937 if( dat.w_fac == 6 && ter( point( 6, SEEY ) ) != t_slope_down ) {
4938 open.push_back( direction::WEST );
4939 }
4940
4941 if( open.empty() ) { // We'll have to build it in the center
4942 int tries = 0;
4943 point p;
4944 bool okay = true;
4945 do {
4946 p.x = rng( SEEX - 6, SEEX + 1 );
4947 p.y = rng( SEEY - 6, SEEY + 1 );
4948 okay = true;
4949 for( int i = p.x; ( i <= p.x + 5 ) && okay; i++ ) {
4950 for( int j = p.y; ( j <= p.y + 5 ) && okay; j++ ) {
4951 if( ter( point( i, j ) ) != t_rock_floor ) {
4952 okay = false;
4953 }
4954 }
4955 }
4956 if( !okay ) {
4957 tries++;
4958 }
4959 } while( !okay && tries < 10 );
4960 if( tries == 10 ) { // Clear the area around the slope down
4961 square( this, t_rock_floor, p, p + point( 5, 5 ) );
4962 }
4963 // NOLINTNEXTLINE(cata-use-named-point-constants)
4964 square( this, t_slope_up, p + point( 1, 1 ), p + point( 2, 2 ) );
4965
4966 } else { // We can build against a wall
4967 switch( random_entry( open ) ) {
4968 case direction::NORTH:
4969 line( this, t_slope_up, point( SEEX - 2, 6 ), point( SEEX + 1, 6 ) );
4970 break;
4971 case direction::EAST:
4972 line( this, t_slope_up, point( SEEX * 2 - 7, SEEY - 2 ), point( SEEX * 2 - 7, SEEY + 1 ) );
4973 break;
4974 case direction::SOUTH:
4975 line( this, t_slope_up, point( SEEX - 2, SEEY * 2 - 7 ), point( SEEX + 1, SEEY * 2 - 7 ) );
4976 break;
4977 case direction::WEST:
4978 line( this, t_slope_up, point( 6, SEEY - 2 ), point( 6, SEEY + 1 ) );
4979 break;
4980 default:
4981 break;
4982 }
4983 }
4984 } // Done building a slope up
4985 } else if( terrain_type == "mine_finale" ) {
4986 // Set up the basic chamber
4987 for( int i = 0; i < SEEX * 2; i++ ) {
4988 for( int j = 0; j < SEEY * 2; j++ ) {
4989 if( i > rng( 1, 3 ) && i < SEEX * 2 - rng( 2, 4 ) &&
4990 j > rng( 1, 3 ) && j < SEEY * 2 - rng( 2, 4 ) ) {
4991 ter_set( point( i, j ), t_rock_floor );
4992 } else {
4993 ter_set( point( i, j ), t_rock );
4994 }
4995 }
4996 }
4997
4998 // Now draw the entrance(s)
4999 if( dat.north() == "mine" ) {
5000 square( this, t_rock_floor, point( SEEX, 0 ), point( SEEX + 1, 3 ) );
5001 }
5002
5003 if( dat.east() == "mine" ) {
5004 square( this, t_rock_floor, point( SEEX * 2 - 4, SEEY ), point( EAST_EDGE, SEEY + 1 ) );
5005 }
5006
5007 if( dat.south() == "mine" ) {
5008 square( this, t_rock_floor, point( SEEX, SEEY * 2 - 4 ), point( SEEX + 1, SOUTH_EDGE ) );
5009 }
5010
5011 if( dat.west() == "mine" ) {
5012 square( this, t_rock_floor, point( 0, SEEY ), point( 3, SEEY + 1 ) );
5013 }
5014
5015 // Now, pick and generate a type of finale!
5016 // The Thing dog
5017 const int num_bodies = rng( 4, 8 );
5018 for( int i = 0; i < num_bodies; i++ ) {
5019 point p3( rng( 4, SEEX * 2 - 5 ), rng( 4, SEEX * 2 - 5 ) );
5020 add_item( p3, item::make_corpse() );
5021 place_items( item_group_id( "mine_equipment" ), 60, p3,
5022 p3, false, calendar::start_of_cataclysm );
5023 }
5024 place_spawns( GROUP_DOG_THING, 1, point( SEEX, SEEX ), point( SEEX + 1, SEEX + 1 ), 1, true, true );
5025 spawn_artifact( tripoint( rng( SEEX, SEEX + 1 ), rng( SEEY, SEEY + 1 ), abs_sub.z ) );
5026 }
5027}
void spawn_artifact(const tripoint &p)
Definition: map.cpp:4173
static void open()
furn_id f_wreckage
Definition: mapdata.cpp:1097
ter_id t_rock
Definition: mapdata.cpp:673
ter_id t_lava
Definition: mapdata.cpp:695
void square(map *m, const ter_id &type, const point &p1, const point &p2)
Definition: mapgen.cpp:6475
static const mongroup_id GROUP_DOG_THING("GROUP_DOG_THING")

References mapgendata::above(), abs_sub, add_field(), add_item(), mapgendata::e_fac, EAST, mapgendata::east(), EAST_EDGE, f_wreckage, fd_gas_vent, GROUP_DOG_THING, is_ot_match(), line(), item::make_corpse(), make_rubble(), move_cost(), mapgendata::n_fac, NORTH, mapgendata::north(), num, one_in(), open(), place_items(), place_spawns(), prefix, random_entry(), random_point(), rng(), mapgendata::s_fac, SEEX, SEEY, SOUTH, mapgendata::south(), SOUTH_EDGE, spawn_artifact(), square(), calendar::start_of_cataclysm, t_lava, t_rock, t_rock_floor, t_slope_down, t_slope_up, ter(), ter_set(), mapgendata::terrain_type(), mapgendata::w_fac, WEST, mapgendata::west(), point::x, point::y, and tripoint::z.

Referenced by draw_map().

◆ draw_office_tower()

void map::draw_office_tower ( mapgendata dat)
protected

Definition at line 2931 of file mapgen.cpp.

2932{
2933 const oter_id &terrain_type = dat.terrain_type();
2934 const auto place_office_chairs = [&]() {
2935 int num_chairs = rng( 0, 6 );
2936 for( int i = 0; i < num_chairs; i++ ) {
2937 add_vehicle( vproto_id( "swivel_chair" ), point( rng( 6, 16 ), rng( 6, 16 ) ),
2938 0_degrees, -1, -1, false );
2939 }
2940 };
2941
2942 const auto ter_key = mapf::ter_bind( "E > < R # X G C , _ r V H 6 x % ^ . - | "
2943 "t + = D w T S e o h c d l s", t_elevator, t_stairs_down,
2951 const auto fur_key = mapf::furn_bind( "E > < R # X G C , _ r V H 6 x % ^ . - | "
2952 "t + = D w T S e o h c d l s", f_null, f_null, f_null,
2958 f_null );
2959 const auto b_ter_key = mapf::ter_bind( "E s > < R # X G C , . r V H 6 x % ^ _ - | "
2960 "t + = D w T S e o h c d l", t_elevator, t_rock,
2968 t_floor, t_floor );
2969 const auto b_fur_key = mapf::furn_bind( "E s > < R # X G C , . r V H 6 x % ^ _ - | "
2970 "t + = D w T S e o h c d l", f_null, f_null, f_null,
2977
2978 if( terrain_type == "office_tower_1_entrance" ) {
2979 dat.fill_groundcover();
2981 "ss%|....+...|...|EEED...\n"
2982 "ss%|----|...|...|EEx|...\n"
2983 "ss%Vcdc^|...|-+-|---|...\n"
2984 "ss%Vch..+...............\n"
2985 "ss%V....|...............\n"
2986 "ss%|----|-|-+--ccc--|...\n"
2987 "ss%|..C..C|.....h..r|-+-\n"
2988 "sss=......+..h.....r|...\n"
2989 "ss%|r..CC.|.ddd....r|T.S\n"
2990 "ss%|------|---------|---\n"
2991 "ss%|####################\n"
2992 "ss%|#|------||------|###\n"
2993 "ss%|#|......||......|###\n"
2994 "ss%|||......||......|###\n"
2995 "ss%||x......||......||##\n"
2996 "ss%|||......||......x|##\n"
2997 "ss%|#|......||......||##\n"
2998 "ss%|#|......||......|###\n"
2999 "ss%|#|XXXXXX||XXXXXX|###\n"
3000 "ss%|-|__,,__||__,,__|---\n"
3001 "ss%% x_,,,,_ __,,__ %%\n"
3002 "ss __,,__ _,,,,_ \n"
3003 "ssssss__,,__ss__,,__ssss\n"
3004 "ssssss______ss______ssss\n", ter_key, fur_key );
3005 place_items( item_group_id( "office" ), 75, point( 4, 2 ), point( 6, 2 ), false,
3007 place_items( item_group_id( "office" ), 75, point( 19, 6 ), point( 19, 6 ), false,
3009 place_items( item_group_id( "office" ), 75, point( 12, 8 ), point( 14, 8 ), false,
3011 if( dat.monster_density() > 1 ) {
3013 } else {
3014 place_spawns( GROUP_PLAIN, 2, point( 15, 1 ), point( 22, 7 ), 1, true );
3015 place_spawns( GROUP_PLAIN, 2, point( 15, 1 ), point( 22, 7 ), 0.15 );
3016 place_spawns( GROUP_ZOMBIE_COP, 2, point( 10, 10 ), point( 14, 10 ), 0.1 );
3017 }
3018 place_office_chairs();
3019
3020 if( dat.north() == "office_tower_1" && dat.west() == "office_tower_1" ) {
3021 rotate( 3 );
3022 } else if( dat.north() == "office_tower_1" && dat.east() == "office_tower_1" ) {
3023 rotate( 0 );
3024 } else if( dat.south() == "office_tower_1" && dat.east() == "office_tower_1" ) {
3025 rotate( 1 );
3026 } else if( dat.west() == "office_tower_1" && dat.south() == "office_tower_1" ) {
3027 rotate( 2 );
3028 }
3029 } else if( terrain_type == "office_tower_1" ) {
3030 // Init to grass & dirt;
3031 dat.fill_groundcover();
3032 if( ( dat.south() == "office_tower_1_entrance" && dat.east() == "office_tower_1" ) ||
3033 ( dat.north() == "office_tower_1" && dat.east() == "office_tower_1_entrance" ) ||
3034 ( dat.west() == "office_tower_1" && dat.north() == "office_tower_1_entrance" ) ||
3035 ( dat.south() == "office_tower_1" && dat.west() == "office_tower_1_entrance" ) ) {
3037 " ssssssssssssssssssssssss\n"
3038 "ssssssssssssssssssssssss\n"
3039 "ss \n"
3040 "ss%%%%%%%%%%%%%%%%%%%%%%\n"
3041 "ss%|-HH-|-HH-|-HH-|HH|--\n"
3042 "ss%Vdcxl|dxdl|lddx|..|.S\n"
3043 "ss%Vdh..|dh..|..hd|..+..\n"
3044 "ss%|-..-|-..-|-..-|..|--\n"
3045 "ss%V.................|.T\n"
3046 "ss%V.................|..\n"
3047 "ss%|-..-|-..-|-..-|..|--\n"
3048 "ss%V.h..|..hd|..hd|..|..\n"
3049 "ss%Vdxdl|^dxd|.xdd|..G..\n"
3050 "ss%|----|----|----|..G..\n"
3051 "ss%|llll|..htth......|..\n"
3052 "ss%V.................|..\n"
3053 "ss%V.ddd..........|+-|..\n"
3054 "ss%|..hd|.hh.ceocc|.l|..\n"
3055 "ss%|----|---------|--|..\n"
3056 "ss%Vcdcl|...............\n"
3057 "ss%V.h..+...............\n"
3058 "ss%V...^|...|---|---|...\n"
3059 "ss%|----|...|.R>|EEE|...\n"
3060 "ss%|rrrr|...|.R.|EEED...\n", ter_key, fur_key );
3061 if( dat.monster_density() > 1 ) {
3063 } else {
3064 place_spawns( GROUP_PLAIN, 1, point( 5, 7 ), point( 15, 20 ), 0.1 );
3065 }
3066 place_items( item_group_id( "office" ), 75, point( 4, 23 ), point( 7, 23 ), false,
3068 place_items( item_group_id( "office" ), 75, point( 4, 19 ), point( 7, 19 ), false,
3070 place_items( item_group_id( "office" ), 75, point( 4, 14 ), point( 7, 14 ), false,
3072 place_items( item_group_id( "office" ), 75, point( 5, 16 ), point( 7, 16 ), false,
3074 place_items( item_group_id( "fridge" ), 80, point( 14, 17 ), point( 14, 17 ), false,
3076 place_items( item_group_id( "cleaning" ), 75, point( 19, 17 ), point( 20, 17 ), false,
3078 place_items( item_group_id( "cubical_office" ), 75, point( 6, 12 ), point( 7, 12 ), false,
3080 place_items( item_group_id( "cubical_office" ), 75, point( 12, 11 ), point( 12, 12 ), false,
3082 place_items( item_group_id( "cubical_office" ), 75, point( 16, 11 ), point( 17, 12 ), false,
3084 place_items( item_group_id( "cubical_office" ), 75, point( 4, 5 ), point( 5, 5 ), false,
3086 place_items( item_group_id( "cubical_office" ), 75, point( 11, 5 ), point( 12, 5 ), false,
3088 place_items( item_group_id( "cubical_office" ), 75, point( 14, 5 ), point( 16, 5 ), false,
3090 place_office_chairs();
3091
3092 if( dat.west() == "office_tower_1_entrance" ) {
3093 rotate( 1 );
3094 }
3095 if( dat.north() == "office_tower_1_entrance" ) {
3096 rotate( 2 );
3097 }
3098 if( dat.east() == "office_tower_1_entrance" ) {
3099 rotate( 3 );
3100 }
3101 } else if( ( dat.west() == "office_tower_1_entrance" && dat.north() == "office_tower_1" ) ||
3102 ( dat.north() == "office_tower_1_entrance" && dat.east() == "office_tower_1" ) ||
3103 ( dat.west() == "office_tower_1" && dat.south() == "office_tower_1_entrance" ) ||
3104 ( dat.south() == "office_tower_1" && dat.east() == "office_tower_1_entrance" ) ) {
3106 "...DEEE|...|..|-----|%ss\n"
3107 "...|EEE|...|..|^...lV%ss\n"
3108 "...|---|-+-|......hdV%ss\n"
3109 "...........G..|..dddV%ss\n"
3110 "...........G..|-----|%ss\n"
3111 ".......|---|..|...ddV%ss\n"
3112 "|+-|...|...+......hdV%ss\n"
3113 "|.l|...|rr.|.^|l...dV%ss\n"
3114 "|--|...|---|--|-----|%ss\n"
3115 "|...........c.......V%ss\n"
3116 "|.......cxh.c.#####.Vsss\n"
3117 "|.......ccccc.......Gsss\n"
3118 "|...................Gsss\n"
3119 "|...................Vsss\n"
3120 "|#..................Gsss\n"
3121 "|#..................Gsss\n"
3122 "|#..................Vsss\n"
3123 "|#............#####.V%ss\n"
3124 "|...................|%ss\n"
3125 "--HHHHHGGHHGGHHHHH--|%ss\n"
3126 "%%%%% ssssssss %%%%%%%ss\n"
3127 " ssssssss ss\n"
3128 "ssssssssssssssssssssssss\n"
3129 "ssssssssssssssssssssssss\n", ter_key, fur_key );
3130 place_items( item_group_id( "office" ), 75, point( 19, 1 ), point( 19, 3 ), false,
3132 place_items( item_group_id( "office" ), 75, point( 17, 3 ), point( 18, 3 ), false,
3134 place_items( item_group_id( "office" ), 90, point( 8, 7 ), point( 9, 7 ), false,
3136 place_items( item_group_id( "cubical_office" ), 75, point( 19, 5 ), point( 19, 7 ), false,
3138 place_items( item_group_id( "cleaning" ), 80, point( 1, 7 ), point( 2, 7 ), false,
3140 if( dat.monster_density() > 1 ) {
3141 place_spawns( GROUP_ZOMBIE, 2, point_zero, point( 14, 10 ), dat.monster_density() );
3142 } else {
3143 place_spawns( GROUP_PLAIN, 1, point( 10, 10 ), point( 14, 10 ), 0.15 );
3144 place_spawns( GROUP_ZOMBIE_COP, 2, point( 10, 10 ), point( 14, 10 ), 0.1 );
3145 }
3146 place_office_chairs();
3147
3148 if( dat.north() == "office_tower_1_entrance" ) {
3149 rotate( 1 );
3150 }
3151 if( dat.east() == "office_tower_1_entrance" ) {
3152 rotate( 2 );
3153 }
3154 if( dat.south() == "office_tower_1_entrance" ) {
3155 rotate( 3 );
3156 }
3157 } else {
3159 "ssssssssssssssssssssssss\n"
3160 "ssssssssssssssssssssssss\n"
3161 " ss\n"
3162 "%%%%%%%%%%%%%%%%%%%%%%ss\n"
3163 "--|---|--HHHH-HHHH--|%ss\n"
3164 ".T|..l|............^|%ss\n"
3165 "..|-+-|...hhhhhhh...V%ss\n"
3166 "--|...G...ttttttt...V%ss\n"
3167 ".S|...G...ttttttt...V%ss\n"
3168 "..+...|...hhhhhhh...V%ss\n"
3169 "--|...|.............|%ss\n"
3170 "..|...|-------------|%ss\n"
3171 "..G....|l.......dxd^|%ss\n"
3172 "..G....G...h....dh..V%ss\n"
3173 "..|....|............V%ss\n"
3174 "..|....|------|llccc|%ss\n"
3175 "..|...........|-----|%ss\n"
3176 "..|...........|...ddV%ss\n"
3177 "..|----|---|......hdV%ss\n"
3178 ".......+...|..|l...dV%ss\n"
3179 ".......|rrr|..|-----|%ss\n"
3180 "...|---|---|..|l.dddV%ss\n"
3181 "...|xEE|.R>|......hdV%ss\n"
3182 "...DEEE|.R.|..|.....V%ss\n", ter_key, fur_key );
3183 spawn_item( point( 18, 15 ), "record_accounting" );
3184 place_items( item_group_id( "cleaning" ), 75, point( 3, 5 ), point( 5, 5 ), false,
3186 place_items( item_group_id( "office" ), 75, point( 10, 7 ), point( 16, 8 ), false,
3188 place_items( item_group_id( "cubical_office" ), 75, point( 15, 15 ), point( 19, 15 ), false,
3190 place_items( item_group_id( "cubical_office" ), 75, point( 16, 12 ), point( 16, 13 ), false,
3192 place_items( item_group_id( "cubical_office" ), 75, point( 17, 19 ), point( 19, 19 ), false,
3194 place_items( item_group_id( "office" ), 75, point( 17, 21 ), point( 19, 21 ), false,
3196 place_items( item_group_id( "office" ), 75, point( 16, 11 ), point( 17, 12 ), false,
3198 place_items( item_group_id( "cleaning" ), 75, point( 8, 20 ), point( 10, 20 ), false,
3200 if( dat.monster_density() > 1 ) {
3202 } else {
3203 place_spawns( GROUP_PLAIN, 1, point_zero, point( 9, 15 ), 0.1 );
3204 }
3205 place_office_chairs();
3206
3207 if( dat.west() == "office_tower_1" && dat.north() == "office_tower_1" ) {
3208 rotate( 1 );
3209 } else if( dat.east() == "office_tower_1" && dat.north() == "office_tower_1" ) {
3210 rotate( 2 );
3211 } else if( dat.east() == "office_tower_1" && dat.south() == "office_tower_1" ) {
3212 rotate( 3 );
3213 }
3214 }
3215 } else if( terrain_type == "office_tower_b_entrance" ) {
3216 dat.fill_groundcover();
3218 "sss|........|...|EEED___\n"
3219 "sss|........|...|EEx|___\n"
3220 "sss|........|-+-|---|HHG\n"
3221 "sss|....................\n"
3222 "sss|....................\n"
3223 "sss|....................\n"
3224 "sss|....................\n"
3225 "sss|....,,......,,......\n"
3226 "sss|...,,,,.....,,......\n"
3227 "sss|....,,.....,,,,..xS.\n"
3228 "sss|....,,......,,...SS.\n"
3229 "sss|-|XXXXXX||XXXXXX|---\n"
3230 "sss|s|EEEEEE||EEEEEE|sss\n"
3231 "sss|||EEEEEE||EEEEEE|sss\n"
3232 "sss||xEEEEEE||EEEEEE||ss\n"
3233 "sss|||EEEEEE||EEEEEEx|ss\n"
3234 "sss|s|EEEEEE||EEEEEE||ss\n"
3235 "sss|s|EEEEEE||EEEEEE|sss\n"
3236 "sss|s|------||------|sss\n"
3237 "sss|--------------------\n"
3238 "ssssssssssssssssssssssss\n"
3239 "ssssssssssssssssssssssss\n"
3240 "ssssssssssssssssssssssss\n"
3241 "ssssssssssssssssssssssss\n", ter_key, fur_key );
3242 if( dat.monster_density() > 1 ) {
3244 } else {
3246 }
3247 if( dat.north() == "office_tower_b" && dat.west() == "office_tower_b" ) {
3248 rotate( 3 );
3249 } else if( dat.north() == "office_tower_b" && dat.east() == "office_tower_b" ) {
3250 rotate( 0 );
3251 } else if( dat.south() == "office_tower_b" && dat.east() == "office_tower_b" ) {
3252 rotate( 1 );
3253 } else if( dat.west() == "office_tower_b" && dat.south() == "office_tower_b" ) {
3254 rotate( 2 );
3255 }
3256 } else if( terrain_type == "office_tower_b" ) {
3257 // Init to grass & dirt;
3258 dat.fill_groundcover();
3259 if( ( dat.south() == "office_tower_b_entrance" && dat.east() == "office_tower_b" ) ||
3260 ( dat.north() == "office_tower_b" && dat.east() == "office_tower_b_entrance" ) ||
3261 ( dat.west() == "office_tower_b" && dat.north() == "office_tower_b_entrance" ) ||
3262 ( dat.south() == "office_tower_b" && dat.west() == "office_tower_b_entrance" ) ) {
3264 "ssssssssssssssssssssssss\n"
3265 "ssssssssssssssssssssssss\n"
3266 "sss|--------------------\n"
3267 "sss|,.....,.....,.....,S\n"
3268 "sss|,.....,.....,.....,S\n"
3269 "sss|,.....,.....,.....,S\n"
3270 "sss|,.....,.....,.....,S\n"
3271 "sss|,.....,.....,.....,S\n"
3272 "sss|,.....,.....,.....,S\n"
3273 "sss|....................\n"
3274 "sss|....................\n"
3275 "sss|....................\n"
3276 "sss|....................\n"
3277 "sss|....................\n"
3278 "sss|....................\n"
3279 "sss|...,,...,....,....,S\n"
3280 "sss|..,,,,..,....,....,S\n"
3281 "sss|...,,...,....,....,S\n"
3282 "sss|...,,...,....,....,S\n"
3283 "sss|........,....,....,S\n"
3284 "sss|........,....,....,S\n"
3285 "sss|........|---|---|HHG\n"
3286 "sss|........|.R<|EEE|___\n"
3287 "sss|........|.R.|EEED___\n", b_ter_key, b_fur_key );
3288 if( dat.monster_density() > 1 ) {
3290 } else {
3292 }
3293 if( dat.west() == "office_tower_b_entrance" ) {
3294 rotate( 1 );
3295 if( x_in_y( 1, 5 ) ) {
3296 add_vehicle( vproto_id( "car" ), point( 17, 7 ), 180_degrees );
3297 }
3298 if( x_in_y( 1, 3 ) ) {
3299 add_vehicle( vproto_id( "motorcycle" ), point( 17, 13 ), 180_degrees );
3300 }
3301 if( x_in_y( 1, 5 ) ) {
3302 if( one_in( 3 ) ) {
3303 add_vehicle( vproto_id( "fire_truck" ), point( 6, 13 ), 0_degrees );
3304 } else {
3305 add_vehicle( vproto_id( "pickup" ), point( 17, 19 ), 180_degrees );
3306 }
3307 }
3308 } else if( dat.north() == "office_tower_b_entrance" ) {
3309 rotate( 2 );
3310 if( x_in_y( 1, 5 ) ) {
3311 add_vehicle( vproto_id( "car" ), point( 10, 17 ), 270_degrees );
3312 }
3313 if( x_in_y( 1, 3 ) ) {
3314 add_vehicle( vproto_id( "motorcycle" ), point( 4, 18 ), 270_degrees );
3315 }
3316 if( x_in_y( 1, 5 ) ) {
3317 if( one_in( 3 ) ) {
3318 add_vehicle( vproto_id( "fire_truck" ), point( 6, 13 ), 0_degrees );
3319 } else {
3320 add_vehicle( vproto_id( "pickup" ), point( 16, 17 ), 270_degrees );
3321 }
3322 }
3323 } else if( dat.east() == "office_tower_b_entrance" ) {
3324 rotate( 3 );
3325 if( x_in_y( 1, 5 ) ) {
3326 add_vehicle( vproto_id( "car" ), point( 6, 4 ), 0_degrees );
3327 }
3328 if( x_in_y( 1, 3 ) ) {
3329 add_vehicle( vproto_id( "motorcycle" ), point( 6, 10 ), 180_degrees );
3330 }
3331 if( x_in_y( 1, 5 ) ) {
3332 add_vehicle( vproto_id( "pickup" ), point( 6, 16 ), 0_degrees );
3333 }
3334
3335 } else {
3336 if( x_in_y( 1, 5 ) ) {
3337 add_vehicle( vproto_id( "pickup" ), point( 7, 6 ), 90_degrees );
3338 }
3339 if( x_in_y( 1, 5 ) ) {
3340 add_vehicle( vproto_id( "car" ), point( 14, 6 ), 90_degrees );
3341 }
3342 if( x_in_y( 1, 3 ) ) {
3343 add_vehicle( vproto_id( "motorcycle" ), point( 19, 6 ), 90_degrees );
3344 }
3345 }
3346 } else if( ( dat.west() == "office_tower_b_entrance" && dat.north() == "office_tower_b" ) ||
3347 ( dat.north() == "office_tower_b_entrance" && dat.east() == "office_tower_b" ) ||
3348 ( dat.west() == "office_tower_b" && dat.south() == "office_tower_b_entrance" ) ||
3349 ( dat.south() == "office_tower_b" && dat.east() == "office_tower_b_entrance" ) ) {
3351 "___DEEE|...|...,,...|sss\n"
3352 "___|EEE|...|..,,,,..|sss\n"
3353 "GHH|---|-+-|...,,...|sss\n"
3354 "....................|sss\n"
3355 "....................|sss\n"
3356 "....................|sss\n"
3357 "....................|sss\n"
3358 "....................|sss\n"
3359 "....................|sss\n"
3360 "....................|sss\n"
3361 "....................|sss\n"
3362 "|...................|sss\n"
3363 "|...................|sss\n"
3364 "|,.....,.....,.....,|sss\n"
3365 "|,.....,.....,.....,|sss\n"
3366 "|,.....,.....,.....,|sss\n"
3367 "|,.....,.....,.....,|sss\n"
3368 "|,.....,.....,.....,|sss\n"
3369 "|,.....,.....,.....,|sss\n"
3370 "|-------------------|sss\n"
3371 "ssssssssssssssssssssssss\n"
3372 "ssssssssssssssssssssssss\n"
3373 "ssssssssssssssssssssssss\n"
3374 "ssssssssssssssssssssssss\n", b_ter_key, b_fur_key );
3375 if( dat.monster_density() > 1 ) {
3377 } else {
3379 }
3380 if( dat.north() == "office_tower_b_entrance" ) {
3381 rotate( 1 );
3382 if( x_in_y( 1, 5 ) ) {
3383 add_vehicle( vproto_id( "car" ), point( 8, 15 ), 0_degrees );
3384 }
3385 if( x_in_y( 1, 5 ) ) {
3386 add_vehicle( vproto_id( "pickup" ), point( 7, 10 ), 180_degrees );
3387 }
3388 if( x_in_y( 1, 3 ) ) {
3389 add_vehicle( vproto_id( "beetle" ), point( 7, 3 ), 0_degrees );
3390 }
3391 } else if( dat.east() == "office_tower_b_entrance" ) {
3392 rotate( 2 );
3393 if( x_in_y( 1, 5 ) ) {
3394 if( one_in( 3 ) ) {
3395 add_vehicle( vproto_id( "fire_truck" ), point( 6, 13 ), 0_degrees );
3396 } else {
3397 add_vehicle( vproto_id( "pickup" ), point( 7, 7 ), 270_degrees );
3398 }
3399 }
3400 if( x_in_y( 1, 5 ) ) {
3401 add_vehicle( vproto_id( "car" ), point( 13, 8 ), 90_degrees );
3402 }
3403 if( x_in_y( 1, 3 ) ) {
3404 add_vehicle( vproto_id( "beetle" ), point( 20, 7 ), 90_degrees );
3405 }
3406 } else if( dat.south() == "office_tower_b_entrance" ) {
3407 rotate( 3 );
3408 if( x_in_y( 1, 5 ) ) {
3409 add_vehicle( vproto_id( "pickup" ), point( 16, 7 ), 0_degrees );
3410 }
3411 if( x_in_y( 1, 5 ) ) {
3412 add_vehicle( vproto_id( "car" ), point( 15, 13 ), 180_degrees );
3413 }
3414 if( x_in_y( 1, 3 ) ) {
3415 add_vehicle( vproto_id( "beetle" ), point( 15, 20 ), 180_degrees );
3416 }
3417 } else {
3418 if( x_in_y( 1, 5 ) ) {
3419 add_vehicle( vproto_id( "pickup" ), point( 16, 16 ), 90_degrees );
3420 }
3421 if( x_in_y( 1, 5 ) ) {
3422 add_vehicle( vproto_id( "car" ), point( 9, 15 ), 270_degrees );
3423 }
3424 if( x_in_y( 1, 3 ) ) {
3425 add_vehicle( vproto_id( "beetle" ), point( 4, 16 ), 270_degrees );
3426 }
3427 }
3428 } else {
3430 "ssssssssssssssssssssssss\n"
3431 "ssssssssssssssssssssssss\n"
3432 "--------------------|sss\n"
3433 "S,.....,.....,.....,|sss\n"
3434 "S,.....,.....,.....,|sss\n"
3435 "S,.....,.....,.....,|sss\n"
3436 "S,.....,.....,.....,|sss\n"
3437 "S,.....,.....,.....,|sss\n"
3438 "S,.....,.....,.....,|sss\n"
3439 "....................|sss\n"
3440 "....................|sss\n"
3441 "....................|sss\n"
3442 "....................|sss\n"
3443 "....................|sss\n"
3444 "....................|sss\n"
3445 "S,....,....,........|sss\n"
3446 "S,....,....,........|sss\n"
3447 "S,....,....,........|sss\n"
3448 "S,....,....,........|sss\n"
3449 "S,....,....,........|sss\n"
3450 "S,....,....,........|sss\n"
3451 "GHH|---|---|........|sss\n"
3452 "___|xEE|.R<|........|sss\n"
3453 "___DEEE|.R.|...,,...|sss\n", b_ter_key, b_fur_key );
3454 if( dat.monster_density() > 1 ) {
3456 } else {
3458 }
3459 if( dat.west() == "office_tower_b" && dat.north() == "office_tower_b" ) {
3460 rotate( 1 );
3461 if( x_in_y( 1, 5 ) ) {
3462 if( one_in( 3 ) ) {
3463 add_vehicle( vproto_id( "cube_van" ), point( 17, 4 ), 180_degrees );
3464 } else {
3465 add_vehicle( vproto_id( "cube_van_cheap" ), point( 17, 4 ), 180_degrees );
3466 }
3467 }
3468 if( x_in_y( 1, 5 ) ) {
3469 add_vehicle( vproto_id( "pickup" ), point( 17, 10 ), 180_degrees );
3470 }
3471 if( x_in_y( 1, 3 ) ) {
3472 add_vehicle( vproto_id( "car" ), point( 17, 17 ), 180_degrees );
3473 }
3474 } else if( dat.east() == "office_tower_b" && dat.north() == "office_tower_b" ) {
3475 rotate( 2 );
3476 if( x_in_y( 1, 5 ) ) {
3477 if( one_in( 3 ) ) {
3478 add_vehicle( vproto_id( "cube_van" ), point( 6, 17 ), 270_degrees );
3479 } else {
3480 add_vehicle( vproto_id( "cube_van_cheap" ), point( 6, 17 ), 270_degrees );
3481 }
3482 }
3483 if( x_in_y( 1, 5 ) ) {
3484 add_vehicle( vproto_id( "pickup" ), point( 12, 17 ), 270_degrees );
3485 }
3486 if( x_in_y( 1, 3 ) ) {
3487 add_vehicle( vproto_id( "fire_truck" ), point( 18, 17 ), 270_degrees );
3488 }
3489 } else if( dat.east() == "office_tower_b" && dat.south() == "office_tower_b" ) {
3490 rotate( 3 );
3491 if( x_in_y( 1, 5 ) ) {
3492 add_vehicle( vproto_id( "cube_van_cheap" ), point( 6, 6 ), 0_degrees );
3493 }
3494 if( x_in_y( 1, 5 ) ) {
3495 if( one_in( 3 ) ) {
3496 add_vehicle( vproto_id( "fire_truck" ), point( 6, 13 ), 0_degrees );
3497 } else {
3498 add_vehicle( vproto_id( "pickup" ), point( 6, 13 ), 0_degrees );
3499 }
3500 }
3501 if( x_in_y( 1, 3 ) ) {
3502 add_vehicle( vproto_id( "car" ), point( 5, 19 ), 180_degrees );
3503 }
3504 } else {
3505 if( x_in_y( 1, 5 ) ) {
3506 add_vehicle( vproto_id( "flatbed_truck" ), point( 16, 6 ), 90_degrees );
3507 }
3508 if( x_in_y( 1, 5 ) ) {
3509 add_vehicle( vproto_id( "cube_van_cheap" ), point( 10, 6 ), 90_degrees );
3510 }
3511 if( x_in_y( 1, 3 ) ) {
3512 add_vehicle( vproto_id( "car" ), point( 4, 6 ), 90_degrees );
3513 }
3514 }
3515 }
3516 }
3517}
bool x_in_y(const time_duration &a, const time_duration &b)
Definition: calendar.cpp:521
void fill_groundcover()
Definition: mapgendata.cpp:125
float monster_density() const
Definition: mapgendata.h:90
furn_id f_chair
Definition: mapdata.cpp:1103
ter_id t_door_locked_alarm
Definition: mapdata.cpp:657
furn_id f_fridge
Definition: mapdata.cpp:1106
ter_id t_wall
Definition: mapdata.cpp:646
furn_id f_bookcase
Definition: mapdata.cpp:1107
ter_id t_pavement
Definition: mapdata.cpp:630
furn_id f_desk
Definition: mapdata.cpp:1103
ter_id t_railing
Definition: mapdata.cpp:688
furn_id f_indoor_plant
Definition: mapdata.cpp:1100
ter_id t_pavement_y
Definition: mapdata.cpp:630
ter_id t_wall_glass
Definition: mapdata.cpp:648
furn_id f_crate_c
Definition: mapdata.cpp:1110
furn_id f_toilet
Definition: mapdata.cpp:1101
ter_id t_window
Definition: mapdata.cpp:666
furn_id f_bench
Definition: mapdata.cpp:1104
ter_id t_door_glass_c
Definition: mapdata.cpp:664
ter_id t_console_broken
Definition: mapdata.cpp:704
ter_id t_door_locked
Definition: mapdata.cpp:657
furn_id f_locker
Definition: mapdata.cpp:1106
ter_id t_elevator
Definition: mapdata.cpp:723
furn_id f_sink
Definition: mapdata.cpp:1102
ter_id t_door_c
Definition: mapdata.cpp:656
static const mongroup_id GROUP_ZOMBIE_COP("GROUP_ZOMBIE_COP")
static const mongroup_id GROUP_PLAIN("GROUP_PLAIN")
static const mongroup_id GROUP_ZOMBIE("GROUP_ZOMBIE")
void formatted_set_simple(map *m, const point &start, const char *cstr, const format_effect< ter_id > &ter_b, const format_effect< furn_id > &furn_b)
Set terrain and furniture on the supplied map.
format_effect< furn_id > furn_bind(const char(&characters)[N], Args... ids)
Definition: mapgenformat.h:76
format_effect< ter_id > ter_bind(const char(&characters)[N], Args... ids)
The functions create a mapping of characters to ids, usable with formatted_set_simple.
Definition: mapgenformat.h:66
string_id< vehicle_prototype > vproto_id
Definition: type_id.h:193

References add_vehicle(), mapgendata::east(), EAST_EDGE, f_bench, f_bookcase, f_chair, f_counter, f_crate_c, f_desk, f_fridge, f_indoor_plant, f_locker, f_null, f_rack, f_sink, f_table, f_toilet, mapgendata::fill_groundcover(), mapf::formatted_set_simple(), mapf::furn_bind(), GROUP_PLAIN, GROUP_ZOMBIE, GROUP_ZOMBIE_COP, mapgendata::monster_density(), mapgendata::north(), one_in(), place_items(), place_spawns(), point_zero, rng(), rotate(), mapgendata::south(), SOUTH_EDGE, spawn_item(), calendar::start_of_cataclysm, t_console, t_console_broken, t_door_c, t_door_glass_c, t_door_locked, t_door_locked_alarm, t_door_metal_locked, t_elevator, t_floor, t_pavement, t_pavement_y, t_railing, t_rock, t_shrub, t_sidewalk, t_stairs_down, t_stairs_up, t_wall, t_wall_glass, t_window, mapf::ter_bind(), mapgendata::terrain_type(), mapgendata::west(), and x_in_y().

Referenced by draw_map().

◆ draw_rough_circle_furn()

void map::draw_rough_circle_furn ( const furn_id type,
const point p,
int  rad 
)

Definition at line 8418 of file map.cpp.

8419{
8420 draw_rough_circle( [this, type]( const point & q ) {
8421 this->furn_set( q, type );
8422 }, p, rad );
8423}

References draw_rough_circle(), furn_set(), and type.

Referenced by rough_circle_furn().

◆ draw_rough_circle_ter()

void map::draw_rough_circle_ter ( const ter_id type,
const point p,
int  rad 
)

Definition at line 8411 of file map.cpp.

8412{
8413 draw_rough_circle( [this, type]( const point & q ) {
8414 this->ter_set( q, type );
8415 }, p, rad );
8416}

References draw_rough_circle(), ter_set(), and type.

Referenced by rough_circle().

◆ draw_slimepit()

void map::draw_slimepit ( mapgendata dat)
protected

Definition at line 5047 of file mapgen.cpp.

5048{
5049 const oter_id &terrain_type = dat.terrain_type();
5050 if( is_ot_match( "slimepit", terrain_type, ot_match_type::prefix ) ) {
5051 for( int i = 0; i < SEEX * 2; i++ ) {
5052 for( int j = 0; j < SEEY * 2; j++ ) {
5053 if( !one_in( 10 ) && ( j < dat.n_fac * SEEX ||
5054 i < dat.w_fac * SEEX ||
5055 j > SEEY * 2 - dat.s_fac * SEEY ||
5056 i > SEEX * 2 - dat.e_fac * SEEX ) ) {
5057 ter_set( point( i, j ), ( !one_in( 10 ) ? t_slime : t_rock_floor ) );
5058 } else if( rng( 0, SEEX ) > std::abs( i - SEEX ) && rng( 0, SEEY ) > std::abs( j - SEEY ) ) {
5059 ter_set( point( i, j ), t_slime );
5060 } else if( dat.zlevel() == 0 ) {
5061 ter_set( point( i, j ), t_dirt );
5062 } else {
5063 ter_set( point( i, j ), t_rock_floor );
5064 }
5065 }
5066 }
5067 if( terrain_type == "slimepit_down" ) {
5068 ter_set( point( rng( 3, SEEX * 2 - 4 ), rng( 3, SEEY * 2 - 4 ) ), t_slope_down );
5069 }
5070 if( dat.above() == "slimepit_down" ) {
5071 switch( rng( 1, 4 ) ) {
5072 case 1:
5073 ter_set( point( rng( 0, 2 ), rng( 0, 2 ) ), t_slope_up );
5074 break;
5075 case 2:
5076 ter_set( point( rng( 0, 2 ), SEEY * 2 - rng( 1, 3 ) ), t_slope_up );
5077 break;
5078 case 3:
5079 ter_set( point( SEEX * 2 - rng( 1, 3 ), rng( 0, 2 ) ), t_slope_up );
5080 break;
5081 case 4:
5082 ter_set( point( SEEX * 2 - rng( 1, 3 ), SEEY * 2 - rng( 1, 3 ) ), t_slope_up );
5083 }
5084 }
5085 place_spawns( GROUP_BLOB, 1, point( SEEX, SEEY ), point( SEEX, SEEY ), 0.15 );
5086 place_items( item_group_id( "sewer" ), 40, point_zero, point( EAST_EDGE, SOUTH_EDGE ), true,
5088 }
5089}
static const mongroup_id GROUP_BLOB("GROUP_BLOB")

References mapgendata::above(), mapgendata::e_fac, EAST_EDGE, GROUP_BLOB, is_ot_match(), mapgendata::n_fac, one_in(), place_items(), place_spawns(), point_zero, prefix, rng(), mapgendata::s_fac, SEEX, SEEY, SOUTH_EDGE, calendar::start_of_cataclysm, t_dirt, t_rock_floor, t_slime, t_slope_down, t_slope_up, ter_set(), mapgendata::terrain_type(), mapgendata::w_fac, and mapgendata::zlevel().

Referenced by draw_map().

◆ draw_square_furn()

void map::draw_square_furn ( const furn_id type,
const point p1,
const point p2 
)

Definition at line 8388 of file map.cpp.

8389{
8390 draw_square( [this, type]( const point & p ) {
8391 this->furn_set( p, type );
8392 }, p1, p2 );
8393}
void draw_square(std::function< void(const point &)>set, point p1, point p2)

References draw_square(), furn_set(), and type.

Referenced by jmapgen_setmap::apply(), mission_start::ranch_nurse_1(), mission_start::ranch_nurse_2(), mission_start::ranch_nurse_7(), mission_start::ranch_nurse_8(), and square_furn().

◆ draw_square_ter() [1/3]

◆ draw_square_ter() [2/3]

void map::draw_square_ter ( const weighted_int_list< ter_id > &  f,
const point p1,
const point p2 
)

Definition at line 8402 of file map.cpp.

8404{
8405 draw_square( [this, f]( const point & p ) {
8406 const ter_id *tid = f.pick();
8407 this->ter_set( p, tid != nullptr ? *tid : t_null );
8408 }, p1, p2 );
8409}
ter_id t_null
Definition: mapdata.cpp:623
const T * pick(unsigned int randi) const
This will return a pointer to an object from the list randomly selected and biased by weight.
Definition: weighted_list.h:94

References draw_square(), weighted_list< W, T >::pick(), t_null, and ter_set().

◆ draw_square_ter() [3/3]

void map::draw_square_ter ( ter_id(*)()  f,
const point p1,
const point p2 
)

Definition at line 8395 of file map.cpp.

8396{
8397 draw_square( [this, f]( const point & p ) {
8398 this->ter_set( p, f() );
8399 }, p1, p2 );
8400}

References draw_square(), and ter_set().

◆ draw_temple()

void map::draw_temple ( mapgendata dat)
protected

Definition at line 4520 of file mapgen.cpp.

4521{
4522 const oter_id &terrain_type = dat.terrain_type();
4523 if( terrain_type == "temple" || terrain_type == "temple_stairs" ) {
4524 if( dat.zlevel() == 0 ) {
4525 // Ground floor
4526 // TODO: More varieties?
4527 fill_background( this, t_dirt );
4528 square( this, t_grate, point( SEEX - 1, SEEY - 1 ), point( SEEX, SEEX ) );
4529 ter_set( point( SEEX + 1, SEEY + 1 ), t_pedestal_temple );
4530 } else {
4531 // Underground! Shit's about to get interesting!
4532 // Start with all rock floor
4534 // We always start at the south and go north.
4535 // We use (y / 2 + z) % 4 to guarantee that rooms don't repeat.
4536 switch( 1 + std::abs( abs_sub.y / 2 + dat.zlevel() + 4 ) % 4 ) { // TODO: More varieties!
4537
4538 case 1:
4539 // Flame bursts
4540 square( this, t_rock, point_zero, point( SEEX - 1, SOUTH_EDGE ) );
4541 square( this, t_rock, point( SEEX + 2, 0 ), point( EAST_EDGE, SOUTH_EDGE ) );
4542 for( int i = 2; i < SEEY * 2 - 4; i++ ) {
4543 add_field( {SEEX, i, abs_sub.z}, fd_fire_vent, rng( 1, 3 ) );
4544 add_field( {SEEX + 1, i, abs_sub.z}, fd_fire_vent, rng( 1, 3 ) );
4545 }
4546 break;
4547
4548 case 2:
4549 // Spreading water
4550 square( this, t_water_dp, point( 4, 4 ), point( 5, 5 ) );
4551 // replaced mon_sewer_snake spawn with GROUP_SEWER
4552 // Decide whether a group of only sewer snakes be made, probably not worth it
4553 place_spawns( GROUP_SEWER, 1, point( 4, 4 ), point( 4, 4 ), 1, true );
4554
4555 square( this, t_water_dp, point( SEEX * 2 - 5, 4 ), point( SEEX * 2 - 4, 6 ) );
4556 place_spawns( GROUP_SEWER, 1, point( 1, SEEX * 2 - 5 ), point( 1, SEEX * 2 - 5 ), 1, true );
4557
4558 square( this, t_water_dp, point( 4, SEEY * 2 - 5 ), point( 6, SEEY * 2 - 4 ) );
4559
4560 square( this, t_water_dp, point( SEEX * 2 - 5, SEEY * 2 - 5 ), point( SEEX * 2 - 4,
4561 SEEY * 2 - 4 ) );
4562
4563 square( this, t_rock, point( 0, SEEY * 2 - 2 ), point( SEEX - 1, SOUTH_EDGE ) );
4564 square( this, t_rock, point( SEEX + 2, SEEY * 2 - 2 ), point( EAST_EDGE, SOUTH_EDGE ) );
4565 line( this, t_grate, point( SEEX, 1 ), point( SEEX + 1, 1 ) ); // To drain the water
4566 mtrap_set( this, point( SEEX, SEEY * 2 - 2 ), tr_temple_flood );
4567 mtrap_set( this, point( SEEX + 1, SEEY * 2 - 2 ), tr_temple_flood );
4568 for( int y = 2; y < SEEY * 2 - 2; y++ ) {
4569 for( int x = 2; x < SEEX * 2 - 2; x++ ) {
4570 if( ter( point( x, y ) ) == t_rock_floor && one_in( 4 ) ) {
4571 mtrap_set( this, point( x, y ), tr_temple_flood );
4572 }
4573 }
4574 }
4575 break;
4576
4577 case 3: { // Flipping walls puzzle
4578 line( this, t_rock, point_zero, point( SEEX - 1, 0 ) );
4579 line( this, t_rock, point( SEEX + 2, 0 ), point( EAST_EDGE, 0 ) );
4580 line( this, t_rock, point( SEEX - 1, 1 ), point( SEEX - 1, 6 ) );
4581 line( this, t_bars, point( SEEX + 2, 1 ), point( SEEX + 2, 6 ) );
4582 ter_set( point( 14, 1 ), t_switch_rg );
4583 ter_set( point( 15, 1 ), t_switch_gb );
4584 ter_set( point( 16, 1 ), t_switch_rb );
4585 ter_set( point( 17, 1 ), t_switch_even );
4586 // Start with clear floors--then work backwards to the starting state
4587 line( this, t_floor_red, point( SEEX, 1 ), point( SEEX + 1, 1 ) );
4588 line( this, t_floor_green, point( SEEX, 2 ), point( SEEX + 1, 2 ) );
4589 line( this, t_floor_blue, point( SEEX, 3 ), point( SEEX + 1, 3 ) );
4590 line( this, t_floor_red, point( SEEX, 4 ), point( SEEX + 1, 4 ) );
4591 line( this, t_floor_green, point( SEEX, 5 ), point( SEEX + 1, 5 ) );
4592 line( this, t_floor_blue, point( SEEX, 6 ), point( SEEX + 1, 6 ) );
4593 // Now, randomly choose actions
4594 // Set up an actions vector so that there's not undue repetition
4595 std::vector<int> actions;
4596 actions.push_back( 1 );
4597 actions.push_back( 2 );
4598 actions.push_back( 3 );
4599 actions.push_back( 4 );
4600 actions.push_back( rng( 1, 3 ) );
4601 while( !actions.empty() ) {
4602 const int action = random_entry_removed( actions );
4603 for( int y = 1; y < 7; y++ ) {
4604 for( int x = SEEX; x <= SEEX + 1; x++ ) {
4605 switch( action ) {
4606 case 1:
4607 // Toggle RG
4608 if( ter( point( x, y ) ) == t_floor_red ) {
4609 ter_set( point( x, y ), t_rock_red );
4610 } else if( ter( point( x, y ) ) == t_rock_red ) {
4611 ter_set( point( x, y ), t_floor_red );
4612 } else if( ter( point( x, y ) ) == t_floor_green ) {
4613 ter_set( point( x, y ), t_rock_green );
4614 } else if( ter( point( x, y ) ) == t_rock_green ) {
4615 ter_set( point( x, y ), t_floor_green );
4616 }
4617 break;
4618 case 2:
4619 // Toggle GB
4620 if( ter( point( x, y ) ) == t_floor_blue ) {
4621 ter_set( point( x, y ), t_rock_blue );
4622 } else if( ter( point( x, y ) ) == t_rock_blue ) {
4623 ter_set( point( x, y ), t_floor_blue );
4624 } else if( ter( point( x, y ) ) == t_floor_green ) {
4625 ter_set( point( x, y ), t_rock_green );
4626 } else if( ter( point( x, y ) ) == t_rock_green ) {
4627 ter_set( point( x, y ), t_floor_green );
4628 }
4629 break;
4630 case 3:
4631 // Toggle RB
4632 if( ter( point( x, y ) ) == t_floor_blue ) {
4633 ter_set( point( x, y ), t_rock_blue );
4634 } else if( ter( point( x, y ) ) == t_rock_blue ) {
4635 ter_set( point( x, y ), t_floor_blue );
4636 } else if( ter( point( x, y ) ) == t_floor_red ) {
4637 ter_set( point( x, y ), t_rock_red );
4638 } else if( ter( point( x, y ) ) == t_rock_red ) {
4639 ter_set( point( x, y ), t_floor_red );
4640 }
4641 break;
4642 case 4:
4643 // Toggle Even
4644 if( y % 2 == 0 ) {
4645 if( ter( point( x, y ) ) == t_floor_blue ) {
4646 ter_set( point( x, y ), t_rock_blue );
4647 } else if( ter( point( x, y ) ) == t_rock_blue ) {
4648 ter_set( point( x, y ), t_floor_blue );
4649 } else if( ter( point( x, y ) ) == t_floor_red ) {
4650 ter_set( point( x, y ), t_rock_red );
4651 } else if( ter( point( x, y ) ) == t_rock_red ) {
4652 ter_set( point( x, y ), t_floor_red );
4653 } else if( ter( point( x, y ) ) == t_floor_green ) {
4654 ter_set( point( x, y ), t_rock_green );
4655 } else if( ter( point( x, y ) ) == t_rock_green ) {
4656 ter_set( point( x, y ), t_floor_green );
4657 }
4658 }
4659 break;
4660 }
4661 }
4662 }
4663 }
4664 }
4665 break;
4666
4667 case 4: { // Toggling walls maze
4668 square( this, t_rock, point_zero, point( SEEX - 1, 1 ) );
4669 square( this, t_rock, point( 0, SEEY * 2 - 2 ), point( SEEX - 1, SOUTH_EDGE ) );
4670 square( this, t_rock, point( 0, 2 ), point( SEEX - 4, SEEY * 2 - 3 ) );
4671 square( this, t_rock, point( SEEX + 2, 0 ), point( EAST_EDGE, 1 ) );
4672 square( this, t_rock, point( SEEX + 2, SEEY * 2 - 2 ), point( EAST_EDGE, SOUTH_EDGE ) );
4673 square( this, t_rock, point( SEEX + 5, 2 ), point( EAST_EDGE, SEEY * 2 - 3 ) );
4674 int x = rng( SEEX - 1, SEEX + 2 ), y = 2;
4675 std::vector<point> path; // Path, from end to start
4676 while( x < SEEX - 1 || x > SEEX + 2 || y < SEEY * 2 - 2 ) {
4677 static const std::vector<ter_id> terrains = {
4679 };
4680 path.push_back( point( x, y ) );
4681 ter_set( point( x, y ), random_entry( terrains ) );
4682 if( y == SEEY * 2 - 2 ) {
4683 if( x < SEEX - 1 ) {
4684 x++;
4685 } else if( x > SEEX + 2 ) {
4686 x--;
4687 }
4688 } else {
4689 std::vector<point> next;
4690 for( int nx = x - 1; nx <= x + 1; nx++ ) {
4691 for( int ny = y; ny <= y + 1; ny++ ) {
4692 if( ter( point( nx, ny ) ) == t_rock_floor ) {
4693 next.push_back( point( nx, ny ) );
4694 }
4695 }
4696 }
4697 if( next.empty() ) {
4698 break;
4699 } else {
4700 const point p = random_entry( next );
4701 x = p.x;
4702 y = p.y;
4703 }
4704 }
4705 }
4706 // Now go backwards through path (start to finish), toggling any tiles that need
4707 bool toggle_red = false;
4708 bool toggle_green = false;
4709 bool toggle_blue = false;
4710 for( int i = path.size() - 1; i >= 0; i-- ) {
4711 if( ter( path[i] ) == t_floor_red ) {
4712 toggle_green = !toggle_green;
4713 if( toggle_red ) {
4714 ter_set( path[i], t_rock_red );
4715 }
4716 } else if( ter( path[i] ) == t_floor_green ) {
4717 toggle_blue = !toggle_blue;
4718 if( toggle_green ) {
4719 ter_set( path[i], t_rock_green );
4720 }
4721 } else if( ter( path[i] ) == t_floor_blue ) {
4722 toggle_red = !toggle_red;
4723 if( toggle_blue ) {
4724 ter_set( path[i], t_rock_blue );
4725 }
4726 }
4727 }
4728 // Finally, fill in the rest with random tiles, and place toggle traps
4729 for( int i = SEEX - 3; i <= SEEX + 4; i++ ) {
4730 for( int j = 2; j <= SEEY * 2 - 2; j++ ) {
4731 mtrap_set( this, point( i, j ), tr_temple_toggle );
4732 if( ter( point( i, j ) ) == t_rock_floor ) {
4733 static const std::vector<ter_id> terrains = {
4736 };
4737 ter_set( point( i, j ), random_entry( terrains ) );
4738 }
4739 }
4740 }
4741 }
4742 break;
4743 } // Done with room type switch
4744 // Stairs down if we need them
4745 if( terrain_type == "temple_stairs" ) {
4746 line( this, t_stairs_down, point( SEEX, 0 ), point( SEEX + 1, 0 ) );
4747 }
4748 // Stairs at the south if dat.above() has stairs down.
4749 if( dat.above() == "temple_stairs" ) {
4750 line( this, t_stairs_up, point( SEEX, SOUTH_EDGE ), point( SEEX + 1, SOUTH_EDGE ) );
4751 }
4752
4753 } // Done with underground-only stuff
4754 } else if( terrain_type == "temple_finale" ) {
4755 fill_background( this, t_rock );
4756 square( this, t_rock_floor, point( SEEX - 1, 1 ), point( SEEX + 2, 4 ) );
4757 square( this, t_rock_floor, point( SEEX, 5 ), point( SEEX + 1, SOUTH_EDGE ) );
4758 line( this, t_stairs_up, point( SEEX, SOUTH_EDGE ), point( SEEX + 1, SOUTH_EDGE ) );
4759 spawn_artifact( tripoint( rng( SEEX, SEEX + 1 ), rng( 2, 3 ), abs_sub.z ) );
4760 spawn_artifact( tripoint( rng( SEEX, SEEX + 1 ), rng( 2, 3 ), abs_sub.z ) );
4761 return;
4762
4763 }
4764}
@ action
Definition: dialogue.h:36
ter_id t_switch_even
Definition: mapdata.cpp:727
ter_id t_rock_red
Definition: mapdata.cpp:726
ter_id t_pedestal_temple
Definition: mapdata.cpp:724
ter_id t_floor_blue
Definition: mapdata.cpp:726
ter_id t_grate
Definition: mapdata.cpp:636
ter_id t_switch_rb
Definition: mapdata.cpp:727
ter_id t_rock_green
Definition: mapdata.cpp:726
ter_id t_rock_blue
Definition: mapdata.cpp:726
ter_id t_floor_green
Definition: mapdata.cpp:726
ter_id t_switch_gb
Definition: mapdata.cpp:727
ter_id t_floor_red
Definition: mapdata.cpp:726
ter_id t_switch_rg
Definition: mapdata.cpp:727
static const mongroup_id GROUP_SEWER("GROUP_SEWER")
static const trap_str_id tr_temple_flood("tr_temple_flood")
generic_factory< oter_t > terrains("overmap terrain")
V random_entry_removed(C &container)
Returns a random entry in the container and removes it from the container.
Definition: rng.h:170
trap_id tr_temple_toggle
Definition: trap.cpp:311

References mapgendata::above(), abs_sub, action, add_field(), EAST_EDGE, fd_fire_vent, fill_background(), GROUP_SEWER, line(), mtrap_set(), one_in(), place_spawns(), point_zero, random_entry(), random_entry_removed(), rng(), SEEX, SEEY, SOUTH_EDGE, spawn_artifact(), square(), t_bars, t_dirt, t_floor_blue, t_floor_green, t_floor_red, t_grate, t_pedestal_temple, t_rock, t_rock_blue, t_rock_floor, t_rock_green, t_rock_red, t_stairs_down, t_stairs_up, t_switch_even, t_switch_gb, t_switch_rb, t_switch_rg, t_water_dp, ter(), ter_set(), mapgendata::terrain_type(), anonymous_namespace{overmap.cpp}::terrains, tr_temple_flood, tr_temple_toggle, point::x, point::y, tripoint::y, tripoint::z, and mapgendata::zlevel().

Referenced by draw_map().

◆ draw_triffid()

void map::draw_triffid ( mapgendata dat)
protected

Definition at line 5091 of file mapgen.cpp.

5092{
5093 const oter_id &terrain_type = dat.terrain_type();
5094 if( terrain_type == "triffid_roots" ) {
5096 int node = 0;
5097 int step = 0;
5098 bool node_built[16];
5099 bool done = false;
5100 for( auto &elem : node_built ) {
5101 elem = false;
5102 }
5103 do {
5104 node_built[node] = true;
5105 step++;
5106 point node2( 1 + 6 * ( node % 4 ), 1 + 6 * static_cast<int>( node / 4 ) );
5107 // Clear a 4x4 dirt square
5108 square( this, t_dirt, node2, node2 + point( 3, 3 ) );
5109 // Spawn a monster in there
5110 if( step > 2 ) { // First couple of chambers are safe
5111 int monrng = rng( 1, 25 );
5112 point spawn( node2 + point{ rng( 0, 3 ), rng( 0, 3 ) } );
5113 if( monrng <= 24 ) {
5115 node2 + point( 3, 3 ), 1, true );
5116 } else {
5117 for( int webx = node2.x; webx <= node2.x + 3; webx++ ) {
5118 for( int weby = node2.y; weby <= node2.y + 3; weby++ ) {
5119 add_field( {webx, weby, abs_sub.z}, fd_web, rng( 1, 3 ) );
5120 }
5121 }
5122 place_spawns( GROUP_SPIDER, 1, spawn, spawn, 1, true );
5123 }
5124 }
5125 // TODO: Non-monster hazards?
5126 // Next, pick a cell to move to
5127 std::vector<direction> move;
5128 if( node % 4 > 0 && !node_built[node - 1] ) {
5129 move.push_back( direction::WEST );
5130 }
5131 if( node % 4 < 3 && !node_built[node + 1] ) {
5132 move.push_back( direction::EAST );
5133 }
5134 if( static_cast<int>( node / 4 ) > 0 && !node_built[node - 4] ) {
5135 move.push_back( direction::NORTH );
5136 }
5137 if( static_cast<int>( node / 4 ) < 3 && !node_built[node + 4] ) {
5138 move.push_back( direction::SOUTH );
5139 }
5140
5141 if( move.empty() ) { // Nowhere to go!
5142 square( this, t_slope_down, node2 + point_south_east, node2 + point( 2, 2 ) );
5143 done = true;
5144 } else {
5145 switch( random_entry( move ) ) {
5146 case direction::NORTH:
5147 square( this, t_dirt, node2 + point( 1, -2 ), node2 + point( 2, -1 ) );
5148 node -= 4;
5149 break;
5150 case direction::EAST:
5151 square( this, t_dirt, node2 + point( 4, 1 ), node2 + point( 5, 2 ) );
5152 node++;
5153 break;
5154 case direction::SOUTH:
5155 square( this, t_dirt, node2 + point( 1, 4 ), node2 + point( 2, 5 ) );
5156 node += 4;
5157 break;
5158 case direction::WEST:
5159 square( this, t_dirt, node2 + point( -2, 1 ), node2 + point( -1, 2 ) );
5160 node--;
5161 break;
5162 default:
5163 break;
5164 }
5165 }
5166 } while( !done );
5167 square( this, t_slope_up, point( 2, 2 ), point( 3, 3 ) );
5168 rotate( rng( 0, 3 ) );
5169 } else if( terrain_type == "triffid_finale" ) {
5171 // NOLINTNEXTLINE(cata-use-named-point-constants)
5172 square( this, t_dirt, point( 1, 1 ), point( 4, 4 ) );
5173 square( this, t_dirt, point( 19, 19 ), point( 22, 22 ) );
5174 // Drunken walk until we reach the heart (lower right, [19, 19])
5175 // Chance increases by 1 each turn, and gives the % chance of forcing a move
5176 // to the right or down.
5177 int chance = 0;
5178 int x = 4;
5179 int y = 4;
5180 do {
5181 ter_set( point( x, y ), t_dirt );
5182
5183 if( chance >= 10 && one_in( 10 ) ) { // Add a spawn
5184 place_spawns( GROUP_TRIFFID, 1, point( x, y ), point( x, y ), 1, true );
5185 }
5186
5187 if( rng( 0, 99 ) < chance ) { // Force movement down or to the right
5188 if( x >= 19 ) {
5189 y++;
5190 } else if( y >= 19 ) {
5191 x++;
5192 } else {
5193 if( one_in( 2 ) ) {
5194 x++;
5195 } else {
5196 y++;
5197 }
5198 }
5199 } else {
5200 chance++; // Increase chance of forced movement down/right
5201 // Weigh movement towards directions with lots of existing walls
5202 int chance_west = 0;
5203 int chance_east = 0;
5204 int chance_north = 0;
5205 int chance_south = 0;
5206 for( int dist = 1; dist <= 5; dist++ ) {
5207 if( ter( point( x - dist, y ) ) == t_root_wall ) {
5208 chance_west++;
5209 }
5210 if( ter( point( x + dist, y ) ) == t_root_wall ) {
5211 chance_east++;
5212 }
5213 if( ter( point( x, y - dist ) ) == t_root_wall ) {
5214 chance_north++;
5215 }
5216 if( ter( point( x, y + dist ) ) == t_root_wall ) {
5217 chance_south++;
5218 }
5219 }
5220 int roll = rng( 0, chance_west + chance_east + chance_north + chance_south );
5221 if( roll < chance_west && x > 0 ) {
5222 x--;
5223 } else if( roll < chance_west + chance_east && x < EAST_EDGE ) {
5224 x++;
5225 } else if( roll < chance_west + chance_east + chance_north && y > 0 ) {
5226 y--;
5227 } else if( y < SOUTH_EDGE ) {
5228 y++;
5229 }
5230 } // Done with drunken walk
5231 } while( x < 19 || y < 19 );
5232 // NOLINTNEXTLINE(cata-use-named-point-constants)
5233 square( this, t_slope_up, point( 1, 1 ), point( 2, 2 ) );
5234 place_spawns( GROUP_TRIFFID_HEART, 1, point( 21, 21 ), point( 21, 21 ), 1, true );
5235
5236 }
5237}
ter_id t_root_wall
Definition: mapdata.cpp:684
static const mongroup_id GROUP_TRIFFID_OUTER("GROUP_TRIFFID_OUTER")
static const mongroup_id GROUP_SPIDER("GROUP_SPIDER")
static const mongroup_id GROUP_TRIFFID("GROUP_TRIFFID")
static const mongroup_id GROUP_TRIFFID_HEART("GROUP_TRIFFID_HEART")

References abs_sub, add_field(), detail::digits::done, EAST, EAST_EDGE, fd_web, fill_background(), GROUP_SPIDER, GROUP_TRIFFID, GROUP_TRIFFID_HEART, GROUP_TRIFFID_OUTER, avatar_action::move(), NORTH, one_in(), place_spawns(), point_south_east, random_entry(), rng(), rotate(), SOUTH, SOUTH_EDGE, square(), t_dirt, t_root_wall, t_slope_down, t_slope_up, ter(), ter_set(), mapgendata::terrain_type(), WEST, point::x, point::y, and tripoint::z.

Referenced by draw_map().

◆ drawsq()

void map::drawsq ( const catacurses::window w,
const tripoint p,
const drawsq_params params 
) const

Draw the map tile at the given coordinate.

Called by map::draw().

Parameters
wThe window we are drawing in
pThe tile on this map to draw.
paramsDraw parameters.

Definition at line 5828 of file map.cpp.

5830{
5831 // If we are in tiles mode, the only thing we want to potentially draw is a highlight
5832 if( is_draw_tiles_mode() ) {
5833 if( params.highlight() ) {
5834 g->draw_highlight( p );
5835 }
5836 return;
5837 }
5838
5839 if( !inbounds( p ) ) {
5840 return;
5841 }
5842
5843 const tripoint view_center = params.center();
5844 const int k = p.x + getmaxx( w ) / 2 - view_center.x;
5845 const int j = p.y + getmaxy( w ) / 2 - view_center.y;
5846 wmove( w, point( k, j ) );
5847
5848 const maptile tile = maptile_at( p );
5849 if( draw_maptile( w, p, tile, params ) ) {
5850 return;
5851 }
5852
5853 tripoint below( p.xy(), p.z - 1 );
5854 const maptile tile_below = maptile_at( below );
5855 draw_from_above( w, below, tile_below, params );
5856}
maptile maptile_at(const tripoint &p) const
Definition: map.cpp:201
constexpr drawsq_params & center(const tripoint &p)
Set view center.
Definition: map.h:283

References drawsq_params::center(), draw_from_above(), draw_maptile(), g, catacurses::getmaxx(), catacurses::getmaxy(), drawsq_params::highlight(), inbounds(), is_draw_tiles_mode(), maptile_at(), catacurses::wmove(), tripoint::x, tripoint::xy(), tripoint::y, and tripoint::z.

Referenced by choose_adjacent_highlight(), anonymous_namespace{animation.cpp}::draw_line_curses(), game::draw_look_around_cursor(), editmap::draw_main_ui_overlay(), target_ui::draw_terrain_overlay(), game::pickup(), place_construction(), and editmap::uber_draw_ter().

◆ drop_everything()

void map::drop_everything ( const tripoint p)

Handles map objects of given type (not creatures) falling down.

Returns true if anything changed.

Definition at line 2045 of file map.cpp.

2046{
2047 //Do a suspension check so that there won't be a floor there for the rest of this check.
2048 if( has_flag( "SUSPENDED", p ) ) {
2050 }
2051 if( has_floor( p ) ) {
2052 return;
2053 }
2054
2055 drop_furniture( p );
2056 drop_items( p );
2057 drop_vehicle( p );
2058 drop_fields( p );
2059}
void drop_furniture(const tripoint &p)
Definition: map.cpp:2061
void drop_items(const tripoint &p)
Definition: map.cpp:2203
void drop_vehicle(const tripoint &p)
Definition: map.cpp:2233
void collapse_invalid_suspension(const tripoint &point)
Triggers a recursive collapse of suspended tiles based on their support validity.
Definition: map.cpp:2952
void drop_fields(const tripoint &p)
Definition: map.cpp:2243
bool has_floor(const tripoint &p) const
Definition: map.cpp:2007

References collapse_invalid_suspension(), drop_fields(), drop_furniture(), drop_items(), drop_vehicle(), has_flag(), and has_floor().

Referenced by process_falling().

◆ drop_fields()

void map::drop_fields ( const tripoint p)

Definition at line 2243 of file map.cpp.

2244{
2245 field &fld = field_at( p );
2246 if( fld.field_count() == 0 ) {
2247 return;
2248 }
2249
2250 std::list<field_type_id> dropped;
2251 const tripoint below = p + tripoint_below;
2252 for( const auto &iter : fld ) {
2253 const field_entry &entry = iter.second;
2254 // For now only drop cosmetic fields, which don't warrant per-turn check
2255 // Active fields "drop themselves"
2256 if( entry.decays_on_actualize() ) {
2257 add_field( below, entry.get_field_type(), entry.get_field_intensity(), entry.get_field_age() );
2258 dropped.push_back( entry.get_field_type() );
2259 }
2260 }
2261
2262 for( const auto &entry : dropped ) {
2263 fld.remove_field( entry );
2264 }
2265}
bool decays_on_actualize() const
Definition: field.h:105

References add_field(), field_entry::decays_on_actualize(), field_at(), field::field_count(), field_entry::get_field_age(), field_entry::get_field_intensity(), field_entry::get_field_type(), field::remove_field(), and tripoint_below.

Referenced by drop_everything().

◆ drop_furniture()

void map::drop_furniture ( const tripoint p)

Definition at line 2061 of file map.cpp.

2062{
2063 const furn_id frn = furn( p );
2064 if( frn == f_null ) {
2065 return;
2066 }
2067
2068 enum support_state {
2069 SS_NO_SUPPORT = 0,
2070 SS_BAD_SUPPORT, // TODO: Implement bad, shaky support
2071 SS_GOOD_SUPPORT,
2072 SS_FLOOR, // Like good support, but bash floor instead of tile below
2073 SS_CREATURE
2074 };
2075
2076 // Checks if the tile:
2077 // has floor (supports unconditionally)
2078 // has support below
2079 // has unsupporting furniture below (bad support, things should "slide" if possible)
2080 // has no support and thus allows things to fall through
2081 const auto check_tile = [this]( const tripoint & pt ) {
2082 if( has_floor( pt ) ) {
2083 return SS_FLOOR;
2084 }
2085
2086 tripoint below_dest( pt.xy(), pt.z - 1 );
2087 if( supports_above( below_dest ) ) {
2088 return SS_GOOD_SUPPORT;
2089 }
2090
2091 const furn_id frn_id = furn( below_dest );
2092 if( frn_id != f_null ) {
2093 const furn_t &frn = frn_id.obj();
2094 // Allow crushing tiny/nocollide furniture
2095 if( !frn.has_flag( "TINY" ) && !frn.has_flag( "NOCOLLIDE" ) ) {
2096 return SS_BAD_SUPPORT;
2097 }
2098 }
2099
2100 if( g->critter_at( below_dest ) != nullptr ) {
2101 // Smash a critter
2102 return SS_CREATURE;
2103 }
2104
2105 return SS_NO_SUPPORT;
2106 };
2107
2108 tripoint current( p.xy(), p.z + 1 );
2109 support_state last_state = SS_NO_SUPPORT;
2110 while( last_state == SS_NO_SUPPORT ) {
2111 current.z--;
2112 // Check current tile
2113 last_state = check_tile( current );
2114 }
2115
2116 if( current == p ) {
2117 // Nothing happened
2118 if( last_state != SS_FLOOR ) {
2119 support_dirty( current );
2120 }
2121
2122 return;
2123 }
2124
2125 furn_set( p, f_null );
2126 furn_set( current, frn );
2127
2128 // If it's sealed, we need to drop items with it
2129 const auto &frn_obj = frn.obj();
2130 if( frn_obj.has_flag( TFLAG_SEALED ) && has_items( p ) ) {
2131 auto old_items = i_at( p );
2132 auto new_items = i_at( current );
2133 for( const auto &it : old_items ) {
2134 new_items.insert( it );
2135 }
2136
2137 i_clear( p );
2138 }
2139
2140 // Approximate weight/"bulkiness" based on strength to drag
2141 int weight;
2142 if( frn_obj.has_flag( "TINY" ) || frn_obj.has_flag( "NOCOLLIDE" ) ) {
2143 weight = 5;
2144 } else {
2145 weight = frn_obj.is_movable() ? frn_obj.move_str_req : 20;
2146 }
2147
2148 if( frn_obj.has_flag( "ROUGH" ) || frn_obj.has_flag( "SHARP" ) ) {
2149 weight += 5;
2150 }
2151
2152 // TODO: Balance this.
2153 int dmg = weight * ( p.z - current.z );
2154
2155 if( last_state == SS_FLOOR ) {
2156 // Bash the same tile twice - once for furniture, once for the floor
2157 bash( current, dmg, false, false, true );
2158 bash( current, dmg, false, false, true );
2159 } else if( last_state == SS_BAD_SUPPORT || last_state == SS_GOOD_SUPPORT ) {
2160 bash( current, dmg, false, false, false );
2161 tripoint below( current.xy(), current.z - 1 );
2162 bash( below, dmg, false, false, false );
2163 } else if( last_state == SS_CREATURE ) {
2164 const std::string &furn_name = frn_obj.name();
2165 bash( current, dmg, false, false, false );
2166 tripoint below( current.xy(), current.z - 1 );
2167 Creature *critter = g->critter_at( below );
2168 if( critter == nullptr ) {
2169 debugmsg( "drop_furniture couldn't find creature at %d,%d,%d",
2170 below.x, below.y, below.z );
2171 return;
2172 }
2173
2174 critter->add_msg_player_or_npc( m_bad, _( "Falling %s hits you!" ),
2175 _( "Falling %s hits <npcname>" ),
2176 furn_name );
2177 // TODO: A chance to dodge/uncanny dodge
2178 player *pl = dynamic_cast<player *>( critter );
2179 monster *mon = dynamic_cast<monster *>( critter );
2180 if( pl != nullptr ) {
2181 pl->deal_damage( nullptr, bodypart_id( "torso" ), damage_instance( DT_BASH, rng( dmg / 3, dmg ), 0,
2182 0.5f ) );
2183 pl->deal_damage( nullptr, bodypart_id( "head" ), damage_instance( DT_BASH, rng( dmg / 3, dmg ), 0,
2184 0.5f ) );
2185 pl->deal_damage( nullptr, bodypart_id( "leg_l" ), damage_instance( DT_BASH, rng( dmg / 2, dmg ), 0,
2186 0.4f ) );
2187 pl->deal_damage( nullptr, bodypart_id( "leg_r" ), damage_instance( DT_BASH, rng( dmg / 2, dmg ), 0,
2188 0.4f ) );
2189 pl->deal_damage( nullptr, bodypart_id( "arm_l" ), damage_instance( DT_BASH, rng( dmg / 2, dmg ), 0,
2190 0.4f ) );
2191 pl->deal_damage( nullptr, bodypart_id( "arm_r" ), damage_instance( DT_BASH, rng( dmg / 2, dmg ), 0,
2192 0.4f ) );
2193 } else if( mon != nullptr ) {
2194 // TODO: Monster's armor and size - don't crush hulks with chairs
2195 mon->apply_damage( nullptr, bodypart_id( "torso" ), rng( dmg, dmg * 2 ) );
2196 }
2197 }
2198
2199 // Re-queue for another check, in case bash destroyed something
2200 support_dirty( current );
2201}
bool supports_above(const tripoint &p) const
Does this tile support vehicles and furniture above it.
Definition: map.cpp:2020
void apply_damage(Creature *source, bodypart_id bp, int dam, bool bypass_med=false) override
Definition: monster.cpp:1661

References _, Creature::add_msg_player_or_npc(), monster::apply_damage(), bash(), Character::deal_damage(), debugmsg, DT_BASH, f_null, furn(), furn_set(), g, map_data_common_t::has_flag(), has_floor(), has_items(), i_at(), i_clear(), m_bad, int_id< T >::obj(), rng(), support_dirty(), supports_above(), TFLAG_SEALED, tripoint::x, tripoint::xy(), tripoint::y, and tripoint::z.

Referenced by drop_everything().

◆ drop_items()

void map::drop_items ( const tripoint p)

Definition at line 2203 of file map.cpp.

2204{
2205 if( !has_items( p ) ) {
2206 return;
2207 }
2208
2209 auto items = i_at( p );
2210 // TODO: Make items check the volume tile below can accept
2211 // rather than disappearing if it would be overloaded
2212
2213 tripoint below( p );
2214 while( !has_floor( below ) ) {
2215 below.z--;
2216 }
2217
2218 if( below == p ) {
2219 return;
2220 }
2221
2222 for( const auto &i : items ) {
2223 // TODO: Bash the item up before adding it
2224 // TODO: Bash the creature, terrain, furniture and vehicles on the tile
2225 add_item_or_charges( below, i );
2226 }
2227
2228 // Just to make a sound for now
2229 bash( below, 1 );
2230 i_clear( p );
2231}

References add_item_or_charges(), bash(), has_floor(), has_items(), i_at(), i_clear(), and tripoint::z.

Referenced by drop_everything().

◆ drop_vehicle()

void map::drop_vehicle ( const tripoint p)

Definition at line 2233 of file map.cpp.

2234{
2235 const optional_vpart_position vp = veh_at( p );
2236 if( !vp ) {
2237 return;
2238 }
2239
2240 vp->vehicle().is_falling = true;
2241}

References veh_at().

Referenced by drop_everything().

◆ emit_field()

void map::emit_field ( const tripoint pos,
const emit_id src,
float  mul = 1.0f 
)

Runs one cycle of emission src which may result in propagation of fields.

Parameters
posLocation of emission
srcId of object producing the emission
mulMultiplies the chance and possibly qty (if chance*mul > 100) of the emission

Definition at line 1928 of file map_field.cpp.

1929{
1930 if( !src.is_valid() ) {
1931 return;
1932 }
1933
1934 const float chance = src->chance() * mul;
1935 if( src.is_valid() && x_in_y( chance, 100 ) ) {
1936 const int qty = chance > 100.0f ? roll_remainder( src->qty() * chance / 100.0f ) : src->qty();
1937 propagate_field( pos, src->field(), qty, src->intensity() );
1938 }
1939}
int intensity() const
Intensity of output fields, range [1..maximum_intensity].
Definition: emit.h:34
int qty() const
Units of field to generate per turn subject to chance.
Definition: emit.h:39
int chance() const
Chance to emit each turn, range [1..100].
Definition: emit.h:44
field_type_id field() const
Type of field to emit.
Definition: emit.h:29
void propagate_field(const tripoint &center, const field_type_id &type, int amount, int max_intensity=0)
Definition: map_field.cpp:1941
bool is_valid() const
Returns whether this id is valid, that means whether it refers to an existing object.
Definition: achievement.cpp:65
int roll_remainder(double value)
Definition: rng.cpp:96

References emit::chance(), emit::field(), emit::intensity(), string_id< T >::is_valid(), propagate_field(), emit::qty(), roll_remainder(), and x_in_y().

Referenced by enchantment::activate_passive(), Character::burn_fuel(), game::do_turn(), Character::heat_emission(), Character::passive_power_gen(), projectile_attack(), and emit_actor::use().

◆ examine()

void map::examine ( Character p,
const tripoint pos 
)

Calls the examine function of furniture or terrain at given tile, for given character.

Examines the tile pos, with character as the "examinator" Casts Character to player because player/NPC split isn't done yet.

Will only examine terrain if furniture had iexamine::none as the examine function.

Definition at line 1620 of file map.cpp.

1621{
1622 const auto furn_here = furn( pos ).obj();
1623 if( furn_here.examine != iexamine::none ) {
1624 furn_here.examine( dynamic_cast<player &>( p ), pos );
1625 } else {
1626 ter( pos ).obj().examine( dynamic_cast<player &>( p ), pos );
1627 }
1628}
void none(player &p, const tripoint &examp)
Nothing player can interact with here.
Definition: iexamine.cpp:247
iexamine_function examine
Definition: mapdata.h:398

References map_data_common_t::examine, furn(), iexamine::none(), int_id< T >::obj(), wrapped_vehicle::pos, and ter().

Referenced by npc::pick_up_item(), and water_from().

◆ features() [1/2]

std::string map::features ( const point p)
inline

Definition at line 964 of file map.h.

964 {
965 return features( tripoint( p, abs_sub.z ) );
966 }
std::string features(const tripoint &p)
Definition: map.cpp:1714

References abs_sub, features(), and tripoint::z.

◆ features() [2/2]

std::string map::features ( const tripoint p)

Definition at line 1714 of file map.cpp.

1715{
1716 std::string result;
1717 const auto add = [&]( const std::string & text ) {
1718 if( !result.empty() ) {
1719 result += " ";
1720 }
1721 result += text;
1722 };
1723 const auto add_if = [&]( const bool cond, const std::string & text ) {
1724 if( cond ) {
1725 add( text );
1726 }
1727 };
1728 // This is used in an info window that is 46 characters wide, and is expected
1729 // to take up one line. So, make sure it does that.
1730 // FIXME: can't control length of localized text.
1731 add_if( is_bashable( p ), _( "Smashable." ) );
1732 add_if( has_flag( "DIGGABLE", p ), _( "Diggable." ) );
1733 add_if( has_flag( "PLOWABLE", p ), _( "Plowable." ) );
1734 add_if( has_flag( "ROUGH", p ), _( "Rough." ) );
1735 add_if( has_flag( "UNSTABLE", p ), _( "Unstable." ) );
1736 add_if( has_flag( "SHARP", p ), _( "Sharp." ) );
1737 add_if( has_flag( "FLAT", p ), _( "Flat." ) );
1738 add_if( has_flag( "EASY_DECONSTRUCT", p ), _( "Simple." ) );
1739 add_if( has_flag( "MOUNTABLE", p ), _( "Mountable." ) );
1740 return result;
1741}
bool is_bashable(const tripoint &p, bool allow_floor=false) const
Returns true if there is a bashable vehicle part or the furn/terrain is bashable at p.
Definition: map.cpp:2414
type add(type dir1, type dir2)
Returns a sum of two numbers.
Definition: overmap.cpp:4192

References _, om_direction::add(), has_flag(), and is_bashable().

Referenced by features(), game::print_terrain_info(), and editmap::update_view_with_help().

◆ field_at() [1/2]

field & map::field_at ( const tripoint p)

Gets fields that are here.

Both for querying and edition.

Definition at line 5303 of file map.cpp.

5304{
5305 if( !inbounds( p ) ) {
5306 nulfield = field();
5307 return nulfield;
5308 }
5309
5310 point l;
5311 submap *const current_submap = get_submap_at( p, l );
5312
5313 return current_submap->get_field( l );
5314}
static field nulfield
Definition: map.cpp:141

References submap::get_field(), get_submap_at(), inbounds(), and nulfield.

◆ field_at() [2/2]

const field & map::field_at ( const tripoint p) const

Get the fields that are here.

This is for querying and looking at it only, one can not change the fields.

Parameters
pThe local map coordinates, if out of bounds, returns an empty field.

Definition at line 5287 of file map.cpp.

5288{
5289 if( !inbounds( p ) ) {
5290 nulfield = field();
5291 return nulfield;
5292 }
5293
5294 point l;
5295 submap *const current_submap = get_submap_at( p, l );
5296
5297 return current_submap->get_field( l );
5298}

References submap::get_field(), get_submap_at(), inbounds(), and nulfield.

Referenced by Character::adjacent_tile(), npc::could_move_onto(), dangerous_field_at(), decay_cosmetic_fields(), editmap_hilight::draw(), editmap::draw_main_ui_overlay(), drop_fields(), get_convection_temperature(), game::get_dangerous_tile(), get_field(), get_field_age(), get_field_intensity(), npc::good_escape_direction(), advanced_inv_area::init(), mop_spills(), game::print_fields_info(), process_fields_in_submap(), smash(), and Character::symbol_color().

◆ fill_funnels()

void map::fill_funnels ( const tripoint p,
const time_point since 
)
protected

Try to fill funnel based items here.

Simulates rain from since till now.

Parameters
pThe location in this map where to fill funnels.

Definition at line 7128 of file map.cpp.

7129{
7130 const auto &tr = tr_at( p );
7131 if( !tr.is_funnel() ) {
7132 return;
7133 }
7134 // Note: the inside/outside cache might not be correct at this time
7136 return;
7137 }
7138 auto items = i_at( p );
7139 units::volume maxvolume = 0_ml;
7140 auto biggest_container = items.end();
7141 for( auto candidate = items.begin(); candidate != items.end(); ++candidate ) {
7142 if( candidate->is_funnel_container( maxvolume ) ) {
7143 biggest_container = candidate;
7144 }
7145 }
7146 if( biggest_container != items.end() ) {
7147 retroactively_fill_from_funnel( *biggest_container, tr, since, calendar::turn, getabs( p ) );
7148 }
7149}
void retroactively_fill_from_funnel(item &it, const trap &tr, const time_point &start, const time_point &end, const tripoint &pos)
Determine what a funnel has filled out of game, using funnelcontainer.bday as a starting point.
Definition: weather.cpp:184

References getabs(), has_flag_ter_or_furn(), i_at(), retroactively_fill_from_funnel(), TFLAG_INDOORS, tr_at(), and calendar::turn.

Referenced by actualize().

◆ find_clear_path()

std::vector< tripoint > map::find_clear_path ( const tripoint source,
const tripoint destination 
) const

Iteratively tries Bresenham lines with different biases until it finds a clear line or decides there isn't one.

returns the line found, which may be the straight line, but blocked.

Definition at line 6261 of file map.cpp.

6263{
6264 // TODO: Push this junk down into the Bresenham method, it's already doing it.
6265 const point d( destination.xy() - source.xy() );
6266 const point a( std::abs( d.x ) * 2, std::abs( d.y ) * 2 );
6267 const int dominant = std::max( a.x, a.y );
6268 const int minor = std::min( a.x, a.y );
6269 // This seems to be the method for finding the ideal start value for the error value.
6270 const int ideal_start_offset = minor - dominant / 2;
6271 const int start_sign = ( ideal_start_offset > 0 ) - ( ideal_start_offset < 0 );
6272 // Not totally sure of the derivation.
6273 const int max_start_offset = std::abs( ideal_start_offset ) * 2 + 1;
6274 for( int horizontal_offset = -1; horizontal_offset <= max_start_offset; ++horizontal_offset ) {
6275 int candidate_offset = horizontal_offset * start_sign;
6276 if( sees( source, destination, rl_dist( source, destination ), candidate_offset ) ) {
6277 return line_to( source, destination, candidate_offset, 0 );
6278 }
6279 }
6280 // If we couldn't find a clear LoS, just return the ideal one.
6281 return line_to( source, destination, ideal_start_offset, 0 );
6282}
bool sees(const tripoint &F, const tripoint &T, int range) const
Returns whether F sees T with a view range of range.
Definition: map.cpp:6130

References a, line_to(), minor, rl_dist(), sees(), point::x, tripoint::xy(), and point::y.

Referenced by mattack::boomer(), mattack::boomer_glow(), leap_actor::call(), mattack::flame(), projectile_attack(), mattack::ranged_pull(), target_ui::set_cursor_pos(), and ranged::targetable_creatures().

◆ find_furnitures_with_flag_in_radius()

std::list< tripoint > map::find_furnitures_with_flag_in_radius ( const tripoint center,
size_t  radius,
const std::string &  flag,
size_t  radiusz = 0 
)

returns positions of furnitures with matching flag in the specified radius

Definition at line 8677 of file map.cpp.

8681{
8682 std::list<tripoint> furn_locs;
8683 for( const auto &furn_loc : points_in_radius( center, radius, radiusz ) ) {
8684 if( has_flag_furn( flag, furn_loc ) ) {
8685 furn_locs.push_back( furn_loc );
8686 }
8687 }
8688 return furn_locs;
8689}

References center, has_flag_furn(), and points_in_radius().

Referenced by activity_handlers::operation_do_turn(), and activity_handlers::operation_finish().

◆ flammable_items_at()

bool map::flammable_items_at ( const tripoint p,
int  threshold = 0 
)

Checks if there are any flammable items on the tile.

Parameters
ptile to check
thresholdFuel threshold (lower means worse fuels are accepted).

Definition at line 2625 of file map.cpp.

2626{
2627 if( !has_items( p ) ||
2629 // Sealed containers don't allow fire, so shouldn't allow setting the fire either
2630 return false;
2631 }
2632
2633 for( const auto &i : i_at( p ) ) {
2634 if( i.flammable( threshold ) ) {
2635 return true;
2636 }
2637 }
2638
2639 return false;
2640}
@ TFLAG_ALLOW_FIELD_EFFECT
Definition: mapdata.h:286

References has_flag(), has_items(), i_at(), TFLAG_ALLOW_FIELD_EFFECT, and TFLAG_SEALED.

Referenced by MapExtras::burned_ground_parser(), is_flammable(), firestarter_actor::moves_cost_by_fuel(), and process_fields_in_submap().

◆ free_volume()

units::volume map::free_volume ( const tripoint p)

Definition at line 4219 of file map.cpp.

4220{
4221 return i_at( p ).free_volume();
4222}
units::volume free_volume() const
Definition: item_stack.cpp:141

References item_stack::free_volume(), and i_at().

Referenced by activity_on_turn_move_loot(), add_item_or_charges(), and advanced_inv_area::free_volume().

◆ function_over()

template<typename Functor >
void map::function_over ( const tripoint start,
const tripoint end,
Functor  fun 
) const
private

Runs a functor over given submaps over submaps in the area, getting next submap only when the current one "runs out" rather than every time.

gp in the functor is Grid (like get_submap_at_grid) coordinate of the submap, Will silently clip the area to map bounds.

Parameters
startStarting point for function
endEnd point for function
funFunction to run

Definition at line 8491 of file map.cpp.

8492{
8493 // start and end are just two points, end can be "before" start
8494 // Also clip the area to map area
8495 const tripoint min( std::max( std::min( start.x, end.x ), 0 ), std::max( std::min( start.y, end.y ),
8496 0 ), std::max( std::min( start.z, end.z ), -OVERMAP_DEPTH ) );
8497 const tripoint max( std::min( std::max( start.x, end.x ), SEEX * my_MAPSIZE - 1 ),
8498 std::min( std::max( start.y, end.y ), SEEY * my_MAPSIZE - 1 ), std::min( std::max( start.z, end.z ),
8499 OVERMAP_HEIGHT ) );
8500
8501 // Submaps that contain the bounding points
8502 const point min_sm( min.x / SEEX, min.y / SEEY );
8503 const point max_sm( max.x / SEEX, max.y / SEEY );
8504 // Z outermost, because submaps are flat
8505 tripoint gp;
8506 int &z = gp.z;
8507 int &smx = gp.x;
8508 int &smy = gp.y;
8509 for( z = min.z; z <= max.z; z++ ) {
8510 for( smx = min_sm.x; smx <= max_sm.x; smx++ ) {
8511 for( smy = min_sm.y; smy <= max_sm.y; smy++ ) {
8512 submap const *cur_submap = get_submap_at_grid( { smx, smy, z } );
8513 // Bounds on the submap coordinates
8514 const point sm_min( smx > min_sm.x ? 0 : min.x % SEEX, smy > min_sm.y ? 0 : min.y % SEEY );
8515 const point sm_max( smx < max_sm.x ? SEEX - 1 : max.x % SEEX,
8516 smy < max_sm.y ? SEEY - 1 : max.y % SEEY );
8517
8518 point lp;
8519 int &sx = lp.x;
8520 int &sy = lp.y;
8521 for( sx = sm_min.x; sx <= sm_max.x; ++sx ) {
8522 for( sy = sm_min.y; sy <= sm_max.y; ++sy ) {
8523 const iteration_state rval = fun( gp, cur_submap, lp );
8524 if( rval != ITER_CONTINUE ) {
8525 switch( rval ) {
8526 case ITER_SKIP_ZLEVEL:
8527 smx = my_MAPSIZE + 1;
8528 smy = my_MAPSIZE + 1;
8529 // Fall through
8530 case ITER_SKIP_SUBMAP:
8531 sx = SEEX;
8532 sy = SEEY;
8533 break;
8534 default:
8535 return;
8536 }
8537 }
8538 }
8539 }
8540 }
8541 }
8542 }
8543}
iteration_state
Enum used by functors in function_over to control execution.
Definition: map.h:1967

References get_submap_at_grid(), ITER_CONTINUE, ITER_SKIP_SUBMAP, ITER_SKIP_ZLEVEL, my_MAPSIZE, OVERMAP_DEPTH, OVERMAP_HEIGHT, SEEX, SEEY, sx, sy, point::x, tripoint::x, point::y, tripoint::y, and tripoint::z.

Referenced by scent_blockers().

◆ furn() [1/2]

furn_id map::furn ( const point p) const
inline

Definition at line 858 of file map.h.

858 {
859 return furn( tripoint( p, abs_sub.z ) );
860 }

References abs_sub, furn(), and tripoint::z.

◆ furn() [2/2]

furn_id map::furn ( const tripoint p) const

Definition at line 1348 of file map.cpp.

1349{
1350 if( !inbounds( p ) ) {
1351 return f_null;
1352 }
1353
1354 point l;
1355 submap *const current_submap = get_submap_at( p, l );
1356
1357 return current_submap->get_furn( l );
1358}
furn_id get_furn(const point &p) const
Definition: submap.h:86

References f_null, submap::get_furn(), get_submap_at(), and inbounds().

Referenced by computer_session::action_blood_anal(), computer_session::action_sample(), actualize(), ter_furn_transform::add_all_messages(), iexamine::arcfurnace_empty(), iexamine::arcfurnace_full(), iexamine::autoclave_full(), bash_furn_success(), bash_rating(), bash_resistance(), bash_strength(), bash_ter_furn(), board_up(), MapExtras::burned_ground_parser(), can_construct(), can_examine_at(), can_move_furniture(), construct::check_deconstruct(), vehicle::autodrive_controller::check_drivable(), deploy_tent_actor::check_intact(), close_door(), doors::close_door(), coverage(), create_anomaly(), MapExtras::dead_vegetation_parser(), iexamine::deployed_furniture(), destroy_furn(), displace_items_except_one_liquid(), game::do_turn(), construct::done_deconstruct(), editmap_hilight::draw(), draw_lab(), editmap::draw_main_ui_overlay(), drop_furniture(), Character::env_surgery_bonus(), examine(), game::examine(), game::extended_description(), computer_session::failure_destroy_blood(), farm_action(), feature< furn_id >(), iexamine::fertilize_plant(), talk_function::field_harvest(), activity_handlers::fill_liquid_do_turn(), find_base_construction(), find_potential_computer_point(), iexamine::fireplace(), Character::floor_bedding_warmth(), inventory::form_from_map(), furn(), furn_is_supported(), furnname(), generic_multi_activity_locations(), get_changed_ids_from_update(), activity_handlers::repair_activity_hack::anonymous_namespace{activity_handlers.cpp}::get_fake_tool(), get_furn_transforms_into(), get_hack_type(), get_harvest(), get_harvest_names(), get_keg_capacity(), grab(), game::grabbed_furn_move(), grow_plant(), activity_handlers::hacksaw_finish(), iexamine::harvest_plant(), has_adjacent_furniture_with(), has_flag_furn(), has_furn(), has_pre_terrain(), is_bashable(), is_bashable_furn(), iexamine::kiln_empty(), iexamine::kiln_full(), talk_function::loot_building(), map_stack::max_volume(), mill_activate(), iexamine::mill_finalize(), mill_load_food(), avatar_action::move(), move_cost(), obstacle_coverage(), om_harvest_furn(), iexamine::on_smoke_out(), open_door(), activity_handlers::oxytorch_finish(), tutorial_game::per_turn(), Character::place_corpse(), game::place_player(), mission_start::place_priest_diary(), activity_handlers::plant_seed_finish(), iexamine::portable_structure(), game::print_terrain_info(), process_items_in_submap(), iexamine::quern_examine(), rad_scorch(), iexamine::reload_furniture(), resolve_regional_terrain_and_furniture(), set_item_map_or_vehicle(), smash(), smoker_activate(), smoker_finalize(), smoker_load_food(), iexamine::smoker_options(), fungal_effects::spread_fungus_one_tile(), ter_furn_transform::transform(), editmap::update_view_with_help(), use_charges(), iexamine::use_furn_fake_item(), game::walk_move(), water_from(), and workbench_crafting_speed_multiplier().

◆ furn_set() [1/2]

void map::furn_set ( const point p,
const furn_id new_furniture 
)
inline

Definition at line 870 of file map.h.

870 {
871 furn_set( tripoint( p, abs_sub.z ), new_furniture );
872 }

References abs_sub, furn_set(), and tripoint::z.

◆ furn_set() [2/2]

void map::furn_set ( const tripoint p,
const furn_id new_furniture,
cata::poly_serialized< active_tile_data new_active = nullptr 
)

Sets the furniture at given position.

Parameters
pPosition within the map
new_furnitureId of new furniture
new_activeOverride default active tile of new furniture

Definition at line 1360 of file map.cpp.

1362{
1363 if( !inbounds( p ) ) {
1364 return;
1365 }
1366
1367 point l;
1368 submap *const current_submap = get_submap_at( p, l );
1369 const furn_id old_id = current_submap->get_furn( l );
1370 if( old_id == new_furniture ) {
1371 // Nothing changed
1372 return;
1373 }
1374
1375 current_submap->set_furn( l, new_furniture );
1376
1377 // Set the dirty flags
1378 const furn_t &old_t = old_id.obj();
1379 const furn_t &new_t = new_furniture.obj();
1380
1381 // If player has grabbed this furniture and it's no longer grabbable, release the grab.
1382 if( g->u.get_grab_type() == OBJECT_FURNITURE && g->u.grab_point == p && !new_t.is_movable() ) {
1383 add_msg( _( "The %s you were grabbing is destroyed!" ), old_t.name() );
1384 g->u.grab( OBJECT_NONE );
1385 }
1386 // If a creature was crushed under a rubble -> free it
1387 if( old_id == f_rubble && new_furniture == f_null ) {
1388 Creature *c = g->critter_at( p );
1389 if( c ) {
1390 c->remove_effect( effect_crushed );
1391 }
1392 }
1393 if( new_t.has_flag( "EMITTER" ) ) {
1394 field_furn_locs.push_back( p );
1395 }
1396 if( old_t.transparent != new_t.transparent ) {
1399 }
1400
1401 if( old_t.has_flag( TFLAG_INDOORS ) != new_t.has_flag( TFLAG_INDOORS ) ) {
1403 }
1404
1405 if( old_t.has_flag( TFLAG_NO_FLOOR ) != new_t.has_flag( TFLAG_NO_FLOOR ) ) {
1408 }
1409
1410 if( old_t.has_flag( TFLAG_SUN_ROOF_ABOVE ) != new_t.has_flag( TFLAG_SUN_ROOF_ABOVE ) ) {
1411 set_floor_cache_dirty( p.z + 1 );
1412 }
1413
1415
1417
1418 // TODO: Limit to changes that affect move cost, traps and stairs
1420
1421 // Make sure the furniture falls if it needs to
1422 support_dirty( p );
1423 tripoint above( p.xy(), p.z + 1 );
1424 // Make sure that if we supported something and no longer do so, it falls down
1425 support_dirty( above );
1426
1427 if( old_t.active ) {
1428 current_submap->active_furniture.erase( point_sm_ms( l ) );
1429 // TODO: Only for g->m? Observer pattern?
1431 }
1432 if( new_t.active || new_active ) {
1434 if( new_active ) {
1435 atd = new_active;
1436 } else {
1437 atd = new_t.active->clone();
1438 atd->set_last_updated( calendar::turn );
1439 }
1440 current_submap->active_furniture[point_sm_ms( l )] = atd;
1442 }
1443}
Copyable unique_ptr that writes and reads objects of derived types.
void on_changed(const tripoint_abs_ms &p)
Updates grid at given global map square coordinate.
void set_floor_cache_dirty(const int zlev)
Definition: map.h:453
void set_memory_seen_cache_dirty(const tripoint &p)
Definition: map.h:468
std::map< point_sm_ms, cata::poly_serialized< active_tile_data > > active_furniture
Definition: submap.h:250
void set_furn(const point &p, furn_id furn)
Definition: submap.h:90
coords::coord_point< point, coords::origin::submap, coords::ms > point_sm_ms
Definition: coordinates.h:473
coords::coord_point< tripoint, coords::origin::abs, coords::ms > tripoint_abs_ms
Definition: coordinates.h:486
distribution_grid_tracker & get_distribution_grid_tracker()
Returns distribution grid tracker that is a part of the global game *g.
Definition: game.cpp:12163
@ OBJECT_NONE
Definition: enums.h:187
@ OBJECT_FURNITURE
Definition: enums.h:197
bool is_movable() const
Definition: mapdata.cpp:1516
cata::poly_serialized< active_tile_data > active
Definition: mapdata.h:519
std::string name() const
Definition: mapdata.cpp:511

References _, furn_t::active, submap::active_furniture, add_msg(), c, effect_crushed, f_null, f_rubble, field_furn_locs, g, get_distribution_grid_tracker(), submap::get_furn(), get_submap_at(), getabs(), map_data_common_t::has_flag(), inbounds(), invalidate_max_populated_zlev(), furn_t::is_movable(), map_data_common_t::name(), int_id< T >::obj(), OBJECT_FURNITURE, OBJECT_NONE, distribution_grid_tracker::on_changed(), set_floor_cache_dirty(), submap::set_furn(), set_memory_seen_cache_dirty(), set_outside_cache_dirty(), set_pathfinding_cache_dirty(), set_seen_cache_dirty(), set_transparency_cache_dirty(), support_dirty(), TFLAG_INDOORS, TFLAG_NO_FLOOR, TFLAG_SUN_ROOF_ABOVE, map_data_common_t::transparent, calendar::turn, tripoint::xy(), and tripoint::z.

Referenced by iexamine::aggie_plant(), jmapgen_sign::apply(), jmapgen_vending_machine::apply(), jmapgen_toilet::apply(), jmapgen_gaspump::apply(), jmapgen_furniture::apply(), jmapgen_terrain::apply(), jmapgen_computer::apply(), jmapgen_sealed_item::apply(), jmapgen_setmap::apply(), apply< furn_t >(), iexamine::arcfurnace_empty(), iexamine::arcfurnace_full(), iexamine::autoclave_full(), bash_furn_success(), board_up(), MapExtras::burned_ground_parser(), activity_handlers::clear_rubble_finish(), close_door(), collapse_at(), collapse_invalid_suspension(), complete_construction(), activity_handlers::cracking_finish(), create_anomaly(), MapExtras::dead_vegetation_parser(), iexamine::deployed_furniture(), displace_items_except_one_liquid(), construct::done_deconstruct(), draw_circle_furn(), draw_lab(), draw_line_furn(), draw_rough_circle_furn(), draw_square_furn(), drop_furniture(), iexamine::egg_sack_generic(), farm_action(), iexamine::fertilize_plant(), talk_function::field_harvest(), activity_handlers::fill_liquid_do_turn(), dig_activity_actor::finish(), hacking_activity_actor::finish(), iexamine::fireplace(), iexamine::flower_cactus(), iexamine::flower_dahlia(), iexamine::flower_marloss(), iexamine::flower_poppy(), mapgen_function_json_base::formatted_set_incredibly_simple(), mapf::formatted_set_simple(), iexamine::fungus(), furn_set(), iexamine::fvat_empty(), iexamine::fvat_full(), game::grabbed_furn_move(), grow_plant(), activity_handlers::hacksaw_finish(), iexamine::harvest_furn(), iexamine::harvest_furn_nectar(), iexamine::harvest_plant(), iexamine::kiln_empty(), iexamine::kiln_full(), talk_function::loot_building(), make_rubble(), mapgen_forest(), mapgen_forest_trail_curved(), mapgen_forest_trail_four_way(), mapgen_forest_trail_straight(), mapgen_forest_trail_tee(), mapgen_lake_shore(), mapgen_tutorial(), iexamine::migo_nerve_cluster(), mill_activate(), iexamine::mill_finalize(), MapExtras::mx_burned_ground(), MapExtras::mx_clay_deposit(), MapExtras::mx_grave(), MapExtras::mx_house_spider(), MapExtras::mx_minefield(), MapExtras::mx_pond(), MapExtras::mx_roadworks(), MapExtras::mx_spider(), MapExtras::mx_supplydrop(), om_harvest_furn(), open_door(), iexamine::open_safe(), activity_handlers::oxytorch_finish(), place_toilet(), place_vending(), activity_handlers::plant_seed_finish(), iexamine::portable_structure(), process_fields_in_submap(), iexamine::quern_examine(), rad_scorch(), mission_start::ranch_nurse_9(), mission_start::ranch_scavenger_3(), resolve_regional_terrain_and_furniture(), iexamine::safe(), science_room(), set(), smoker_activate(), smoker_finalize(), iexamine::smoker_options(), fungal_effects::spread_fungus_one_tile(), ter_or_furn_set(), ter_furn_transform::transform(), deploy_furn_actor::use(), and deploy_tent_actor::use().

◆ furnname() [1/2]

std::string map::furnname ( const point p)
inline

Definition at line 874 of file map.h.

874 {
875 return furnname( tripoint( p, abs_sub.z ) );
876 }
std::string furnname(const tripoint &p)
Definition: map.cpp:1469

References abs_sub, furnname(), and tripoint::z.

◆ furnname() [2/2]

std::string map::furnname ( const tripoint p)

Definition at line 1469 of file map.cpp.

1470{
1471 const furn_t &f = furn( p ).obj();
1472 if( f.has_flag( "PLANT" ) ) {
1473 // Can't use item_stack::only_item() since there might be fertilizer
1474 map_stack items = i_at( p );
1475 const map_stack::iterator seed = std::find_if( items.begin(), items.end(), []( const item & it ) {
1476 return it.is_seed();
1477 } );
1478 if( seed == items.end() ) {
1479 debugmsg( "Missing seed for plant at (%d, %d, %d)", p.x, p.y, p.z );
1480 return "null";
1481 }
1482 const std::string &plant = seed->get_plant_name();
1483 return string_format( "%s (%s)", f.name(), plant );
1484 } else {
1485 return f.name();
1486 }
1487}
iterator begin()
Definition: item_stack.cpp:28
iterator end()
Definition: item_stack.cpp:33
Definition: map.h:105
int seed(player *, item *, bool, const tripoint &)
Definition: iuse.cpp:5999

References item_stack::begin(), debugmsg, item_stack::end(), furn(), map_data_common_t::has_flag(), i_at(), map_data_common_t::name(), int_id< T >::obj(), plant, iuse::seed(), string_format(), tripoint::x, tripoint::y, and tripoint::z.

Referenced by apply_lock_picking_tool(), apply_prying_tool(), activity_handlers::clear_rubble_finish(), iexamine::egg_sack_generic(), iexamine::fireplace(), iexamine::flower_cactus(), iexamine::flower_dahlia(), iexamine::flower_marloss(), iexamine::flower_poppy(), iexamine::fungus(), furnname(), grab(), harvest_common(), iexamine::locked_object(), iexamine::locked_object_pickable(), name(), game::place_player(), game::print_terrain_info(), iexamine::reload_furniture(), iexamine::rubble(), smash(), and deploy_tent_actor::use().

◆ gas_can_spread_to()

bool map::gas_can_spread_to ( field_entry cur,
const tripoint src,
const tripoint dst 
)
private

Definition at line 211 of file map_field.cpp.

212{
213 maptile dst_tile = maptile_at( dst );
214 const field_entry *tmpfld = dst_tile.get_field().find_field( cur.get_field_type() );
215 // Candidates are existing weaker fields or navigable/flagged tiles with no field.
216 if( tmpfld == nullptr || tmpfld->get_field_intensity() < cur.get_field_intensity() ) {
217 const ter_t &ter = dst_tile.get_ter_t();
218 const furn_t &frn = dst_tile.get_furn_t();
219 return !obstructed_by_vehicle_rotation( src, dst ) &&
220 ( ter_furn_movecost( ter, frn ) > 0 || ter_furn_has_flag( ter, frn, TFLAG_PERMEABLE ) );
221 }
222 return false;
223}
bool ter_furn_has_flag(const ter_t &ter, const furn_t &furn, const ter_bitflags flag)
Definition: map_field.cpp:161
static int ter_furn_movecost(const ter_t &ter, const furn_t &furn)
Definition: map_field.cpp:166
@ TFLAG_PERMEABLE
Definition: mapdata.h:304
const ter_t & get_ter_t() const
Definition: submap.h:300
const field & get_field() const
Definition: submap.h:304
const furn_t & get_furn_t() const
Definition: submap.h:297

References field::find_field(), maptile::get_field(), field_entry::get_field_intensity(), field_entry::get_field_type(), maptile::get_furn_t(), maptile::get_ter_t(), maptile_at(), obstructed_by_vehicle_rotation(), ter(), ter_furn_has_flag(), ter_furn_movecost(), and TFLAG_PERMEABLE.

Referenced by spread_gas().

◆ gas_spread_to()

void map::gas_spread_to ( field_entry cur,
maptile dst,
const tripoint p 
)
private

Definition at line 225 of file map_field.cpp.

226{
227 const field_type_id current_type = cur.get_field_type();
228 const time_duration current_age = cur.get_field_age();
229 const int current_intensity = cur.get_field_intensity();
230 field_entry *f = dst.find_field( current_type );
231 // Nearby gas grows thicker, and ages are shared.
232 const time_duration age_fraction = current_age / current_intensity;
233 if( f != nullptr ) {
235 cur.set_field_intensity( current_intensity - 1 );
236 f->set_field_age( f->get_field_age() + age_fraction );
237 cur.set_field_age( current_age - age_fraction );
238 // Or, just create a new field.
239 } else if( add_field( p, current_type, 1, 0_turns ) ) {
240 f = dst.find_field( current_type );
241 if( f != nullptr ) {
242 f->set_field_age( age_fraction );
243 } else {
244 debugmsg( "While spreading the gas, field was added but doesn't exist." );
245 }
246 cur.set_field_intensity( current_intensity - 1 );
247 cur.set_field_age( current_age - age_fraction );
248 }
249}
int set_field_intensity(int new_intensity)
Definition: field.cpp:126
field_entry * find_field(const field_type_id &field_to_find)
Definition: submap.h:308

References add_field(), debugmsg, maptile::find_field(), field_entry::get_field_age(), field_entry::get_field_intensity(), field_entry::get_field_type(), field_entry::set_field_age(), and field_entry::set_field_intensity().

Referenced by spread_gas().

◆ generate()

void map::generate ( const tripoint p,
const time_point when 
)

Definition at line 106 of file mapgen.cpp.

107{
108 dbg( DL::Info ) << "map::generate( g[" << g.get() << "], p[" << p <<
109 "], when[" << to_string( when ) << "] )";
110
111 set_abs_sub( p );
112
113 // First we have to create new submaps and initialize them to 0 all over
114 // We create all the submaps, even if we're not a tinymap, so that map
115 // generation which overflows won't cause a crash. At the bottom of this
116 // function, we save the upper-left 4 submaps, and delete the rest.
117 // Mapgen is not z-level aware yet. Only actually initialize current z-level
118 // because other submaps won't be touched.
119 for( int gridx = 0; gridx < my_MAPSIZE; gridx++ ) {
120 for( int gridy = 0; gridy < my_MAPSIZE; gridy++ ) {
121 const size_t grid_pos = get_nonant( { gridx, gridy, p.z } );
122 if( getsubmap( grid_pos ) ) {
123 debugmsg( "Submap already exists at (%d, %d, %d)", gridx, gridy, p.z );
124 continue;
125 }
126 setsubmap( grid_pos, new submap() );
127 // TODO: memory leak if the code below throws before the submaps get stored/deleted!
128 }
129 }
130 // x, and y are submap coordinates, convert to overmap terrain coordinates
131 // TODO: fix point types
132 tripoint_abs_omt abs_omt( sm_to_omt_copy( p ) );
133 oter_id terrain_type = overmap_buffer.ter( abs_omt );
134
135 // This attempts to scale density of zombies inversely with distance from the nearest city.
136 // In other words, make city centers dense and perimeters sparse.
137 float density = 0.0;
138 for( int i = -MON_RADIUS; i <= MON_RADIUS; i++ ) {
139 for( int j = -MON_RADIUS; j <= MON_RADIUS; j++ ) {
140 density += overmap_buffer.ter( abs_omt + point( i, j ) )->get_mondensity();
141 }
142 }
143 density = density / 100;
144
145 mapgendata dat( abs_omt, *this, density, when, nullptr );
146 draw_map( dat );
147
148 // At some point, we should add region information so we can grab the appropriate extras
149 map_extras ex = region_settings_map["default"].region_extras[terrain_type->get_extras()];
150 if( ex.chance > 0 && one_in( ex.chance ) ) {
151 std::string *extra = ex.values.pick();
152 if( extra == nullptr ) {
153 debugmsg( "failed to pick extra for type %s", terrain_type->get_extras() );
154 } else {
155 MapExtras::apply_function( *( ex.values.pick() ), *this, abs_sub );
156 }
157 }
158
159 const auto &spawns = terrain_type->get_static_spawns();
160
161 float spawn_density = 1.0f;
162 if( MonsterGroupManager::is_animal( spawns.group ) ) {
163 spawn_density = get_option< float >( "SPAWN_ANIMAL_DENSITY" );
164 } else {
165 spawn_density = get_option< float >( "SPAWN_DENSITY" );
166 }
167
168 // Apply a multiplier to the number of monsters for really high densities.
169 float odds_after_density = spawns.chance * spawn_density;
170 const float max_odds = 100 - ( 100 - spawns.chance ) / 2.0;
171 float density_multiplier = 1.0f;
172 if( odds_after_density > max_odds ) {
173 density_multiplier = 1.0f * odds_after_density / max_odds;
174 odds_after_density = max_odds;
175 }
176 const int spawn_count = roll_remainder( density_multiplier );
177
178 if( spawns.group && x_in_y( odds_after_density, 100 ) ) {
179 int pop = spawn_count * rng( spawns.population.min, spawns.population.max );
180 for( ; pop > 0; pop-- ) {
181 MonsterGroupResult spawn_details = MonsterGroupManager::GetResultFromGroup( spawns.group, &pop );
182 if( !spawn_details.name ) {
183 continue;
184 }
185 if( const cata::optional<tripoint> pt =
186 random_point( *this, [this]( const tripoint & n ) {
187 return passable( n );
188 } ) ) {
189 add_spawn( spawn_details.name, spawn_details.pack_size, *pt );
190 }
191 }
192 }
193
194 // Okay, we know who are neighbors are. Let's draw!
195 // And finally save used submaps and delete the rest.
196 for( int i = 0; i < my_MAPSIZE; i++ ) {
197 for( int j = 0; j < my_MAPSIZE; j++ ) {
198 dbg( DL::Info ) << "map::generate: submap (" << i << "," << j << ")";
199
200 const tripoint pos( i, j, p.z );
201 if( i <= 1 && j <= 1 ) {
202 saven( pos );
203 } else {
204 const size_t grid_pos = get_nonant( pos );
205 delete getsubmap( grid_pos );
206 setsubmap( grid_pos, nullptr );
207 }
208 }
209 }
210}
std::string to_string(const time_duration &d)
Returns a string showing a duration.
Definition: calendar.cpp:327
static bool is_animal(const mongroup_id &group)
Definition: mongroup.cpp:401
static MonsterGroupResult GetResultFromGroup(const mongroup_id &group, int *quantity=nullptr)
Definition: mongroup.cpp:98
void saven(const tripoint &grid)
Definition: map.cpp:6937
void set_abs_sub(const tripoint &p)
Sets abs_sub, see there.
Definition: map.cpp:8271
void draw_map(mapgendata &dat)
Definition: mapgen.cpp:2888
submap * getsubmap(size_t grididx) const
Get the submap pointer with given index in grid, the index must be valid!
Definition: map.cpp:8281
void add_spawn(const mtype_id &type, int count, const tripoint &p, bool friendly=false, int faction_id=-1, int mission_id=-1, const std::string &name="NONE") const
Definition: mapgen.cpp:5582
bool passable(const tripoint &p) const
Definition: map.cpp:1800
Contains various information regarding the individual mapgen instance (generating a specific part of ...
Definition: mapgendata.h:36
const oter_id & ter(const tripoint_abs_omt &p)
Returns the overmap terrain at the given OMT coordinates.
point sm_to_omt_copy(const point &p)
static constexpr int MON_RADIUS
Definition: mapgen.cpp:100
void apply_function(const string_id< map_extra > &id, map &m, const tripoint &abs_sub)
t_regional_settings_map region_settings_map
Definition: overmap.cpp:186
mtype_id name
Definition: mongroup.h:53
unsigned int chance
weighted_int_list< std::string > values
const std::string & get_extras() const
Definition: omdata.h:237
const overmap_static_spawns & get_static_spawns() const
Definition: omdata.h:245
int get_mondensity() const
Definition: omdata.h:241

References abs_sub, add_spawn(), MapExtras::apply_function(), map_extras::chance, dbg, debugmsg, draw_map(), g, oter_t::get_extras(), oter_t::get_mondensity(), get_nonant(), oter_t::get_static_spawns(), MonsterGroupManager::GetResultFromGroup(), getsubmap(), Info, MonsterGroupManager::is_animal(), MON_RADIUS, my_MAPSIZE, MonsterGroupResult::name, one_in(), overmap_buffer, MonsterGroupResult::pack_size, passable(), random_point(), region_settings_map, rng(), roll_remainder(), saven(), set_abs_sub(), setsubmap(), sm_to_omt_copy(), overmapbuffer::ter(), to_string(), map_extras::values, x_in_y(), and tripoint::z.

Referenced by farm_action(), defense_game::init_map(), loadn(), and editmap::mapgen_preview().

◆ generate_lightmap()

void map::generate_lightmap ( int  zlev)
protected

Definition at line 371 of file lightmap.cpp.

372{
373 auto &map_cache = get_cache( zlev );
374 auto &lm = map_cache.lm;
375 auto &sm = map_cache.sm;
376 auto &outside_cache = map_cache.outside_cache;
377 auto &prev_floor_cache = get_cache( clamp( zlev + 1, -OVERMAP_DEPTH, OVERMAP_DEPTH ) ).floor_cache;
378 bool top_floor = zlev == OVERMAP_DEPTH;
379 std::memset( lm, 0, sizeof( lm ) );
380 std::memset( sm, 0, sizeof( sm ) );
381
382 /* Bulk light sources wastefully cast rays into neighbors; a burning hospital can produce
383 significant slowdown, so for stuff like fire and lava:
384 * Step 1: Store the position and luminance in buffer via add_light_source, for efficient
385 checking of neighbors.
386 * Step 2: After everything else, iterate buffer and apply_light_source only in non-redundant
387 directions
388 * Step 3: ????
389 * Step 4: Profit!
390 */
391 auto &light_source_buffer = map_cache.light_source_buffer;
392 std::memset( light_source_buffer, 0, sizeof( light_source_buffer ) );
393
394 constexpr std::array<int, 4> dir_x = { { 0, -1, 1, 0 } }; // [0]
395 constexpr std::array<int, 4> dir_y = { { -1, 0, 0, 1 } }; // [1][X][2]
396 constexpr std::array<int, 4> dir_d = { { 90, 0, 180, 270 } }; // [3]
397 constexpr std::array<std::array<quadrant, 2>, 4> dir_quadrants = { {
402 }
403 };
404
405 const float natural_light = g->natural_light_level( zlev );
406
407 build_sunlight_cache( zlev );
408
410 for( npc &guy : g->all_npcs() ) {
412 }
413
414 std::vector<std::pair<tripoint, float>> lm_override;
415 // Traverse the submaps in order
416 for( int smx = 0; smx < my_MAPSIZE; ++smx ) {
417 for( int smy = 0; smy < my_MAPSIZE; ++smy ) {
418 const auto cur_submap = get_submap_at_grid( { smx, smy, zlev } );
419
420 for( int sx = 0; sx < SEEX; ++sx ) {
421 for( int sy = 0; sy < SEEY; ++sy ) {
422 const int x = sx + smx * SEEX;
423 const int y = sy + smy * SEEY;
424 const tripoint p( x, y, zlev );
425 // Project light into any openings into buildings.
426 if( !outside_cache[p.x][p.y] || ( !top_floor && prev_floor_cache[p.x][p.y] ) ) {
427 // Apply light sources for external/internal divide
428 for( int i = 0; i < 4; ++i ) {
429 point neighbour = p.xy() + point( dir_x[i], dir_y[i] );
430 if( lightmap_boundaries.contains( neighbour )
431 && outside_cache[neighbour.x][neighbour.y] &&
432 ( top_floor || !prev_floor_cache[neighbour.x][neighbour.y] )
433 ) {
434 const float source_light =
435 std::min( natural_light, lm[neighbour.x][neighbour.y].max() );
437 update_light_quadrants( lm[p.x][p.y], source_light, quadrant::default_ );
438 apply_directional_light( p, dir_d[i], source_light );
439 } else {
440 update_light_quadrants( lm[p.x][p.y], source_light, dir_quadrants[i][0] );
441 update_light_quadrants( lm[p.x][p.y], source_light, dir_quadrants[i][1] );
442 }
443 }
444 }
445 }
446
447 if( cur_submap->get_lum( { sx, sy } ) && has_items( p ) ) {
448 auto items = i_at( p );
449 add_light_from_items( p, items.begin(), items.end() );
450 }
451
452 const ter_id terrain = cur_submap->get_ter( { sx, sy } );
453 if( terrain->light_emitted > 0 ) {
454 add_light_source( p, terrain->light_emitted );
455 }
456 const furn_id furniture = cur_submap->get_furn( {sx, sy } );
457 if( furniture->light_emitted > 0 ) {
458 add_light_source( p, furniture->light_emitted );
459 }
460
461 for( auto &fld : cur_submap->get_field( { sx, sy } ) ) {
462 const field_entry *cur = &fld.second;
463 const int light_emitted = cur->light_emitted();
464 if( light_emitted > 0 ) {
465 add_light_source( p, light_emitted );
466 }
467 const float light_override = cur->local_light_override();
468 if( light_override >= 0.0 ) {
469 lm_override.push_back( std::pair<tripoint, float>( p, light_override ) );
470 }
471 }
472 }
473 }
474 }
475 }
476
477 for( monster &critter : g->all_monsters() ) {
478 if( critter.is_hallucination() ) {
479 continue;
480 }
481 const tripoint &mp = critter.pos();
482 if( inbounds( mp ) ) {
483 if( critter.has_effect( effect_onfire ) ) {
484 apply_light_source( mp, 8 );
485 }
486 // TODO: [lightmap] Attach natural light brightness to creatures
487 // TODO: [lightmap] Allow creatures to have light attacks (i.e.: eyebot)
488 // TODO: [lightmap] Allow creatures to have facing and arc lights
489 if( critter.type->luminance > 0 ) {
490 apply_light_source( mp, critter.type->luminance );
491 }
492 }
493 }
494
495 // Apply any vehicle light sources
496 VehicleList vehs = get_vehicles();
497 for( auto &vv : vehs ) {
498 vehicle *v = vv.v;
499
500 auto lights = v->lights( true );
501
502 float veh_luminance = 0.0;
503 float iteration = 1.0;
504
505 for( const auto pt : lights ) {
506 const auto &vp = pt->info();
507 if( vp.has_flag( VPFLAG_CONE_LIGHT ) ||
508 vp.has_flag( VPFLAG_WIDE_CONE_LIGHT ) ) {
509 veh_luminance += vp.bonus / iteration;
510 iteration = iteration * 1.1;
511 }
512 }
513
514 for( const auto pt : lights ) {
515 const auto &vp = pt->info();
516 tripoint src = v->global_part_pos3( *pt );
517
518 if( !inbounds( src ) ) {
519 continue;
520 }
521
522 if( vp.has_flag( VPFLAG_CONE_LIGHT ) ) {
523 if( veh_luminance > lit_level::LIT ) {
524 add_light_source( src, M_SQRT2 ); // Add a little surrounding light
525 apply_light_arc( src, v->face.dir() + pt->direction, veh_luminance,
526 45_degrees );
527 }
528
529 } else if( vp.has_flag( VPFLAG_WIDE_CONE_LIGHT ) ) {
530 if( veh_luminance > lit_level::LIT ) {
531 add_light_source( src, M_SQRT2 ); // Add a little surrounding light
532 apply_light_arc( src, v->face.dir() + pt->direction, veh_luminance,
533 90_degrees );
534 }
535
536 } else if( vp.has_flag( VPFLAG_HALF_CIRCLE_LIGHT ) ) {
537 add_light_source( src, M_SQRT2 ); // Add a little surrounding light
538 apply_light_arc( src, v->face.dir() + pt->direction, vp.bonus, 180_degrees );
539
540 } else if( vp.has_flag( VPFLAG_CIRCLE_LIGHT ) ) {
541 const bool odd_turn = calendar::once_every( 2_turns );
542 if( ( odd_turn && vp.has_flag( VPFLAG_ODDTURN ) ) ||
543 ( !odd_turn && vp.has_flag( VPFLAG_EVENTURN ) ) ||
544 ( !( vp.has_flag( VPFLAG_EVENTURN ) || vp.has_flag( VPFLAG_ODDTURN ) ) ) ) {
545
546 add_light_source( src, vp.bonus );
547 }
548
549 } else {
550 add_light_source( src, vp.bonus );
551 }
552 }
553
554 for( const vpart_reference &vp : v->get_all_parts() ) {
555 const size_t p = vp.part_index();
556 const tripoint pp = vp.pos();
557 if( !inbounds( pp ) ) {
558 continue;
559 }
560 if( vp.has_feature( VPFLAG_CARGO ) && !vp.has_feature( "COVERED" ) ) {
561 add_light_from_items( pp, v->get_items( static_cast<int>( p ) ).begin(),
562 v->get_items( static_cast<int>( p ) ).end() );
563 }
564 }
565 }
566
567 /* Now that we have position and intensity of all bulk light sources, apply_ them
568 This may seem like extra work, but take a 12x12 raging inferno:
569 unbuffered: (12^2)*(160*4) = apply_light_ray x 92160
570 buffered: (12*4)*(160) = apply_light_ray x 7680
571 */
572 const tripoint cache_start( 0, 0, zlev );
573 const tripoint cache_end( LIGHTMAP_CACHE_X, LIGHTMAP_CACHE_Y, zlev );
574 for( const tripoint &p : points_in_rectangle( cache_start, cache_end ) ) {
575 if( light_source_buffer[p.x][p.y] > 0.0 ) {
576 apply_light_source( p, light_source_buffer[p.x][p.y] );
577 }
578 }
579 for( const std::pair<tripoint, float> &elem : lm_override ) {
580 lm[elem.first.x][elem.first.y].fill( elem.second );
581 }
582}
float light_emitted() const
Definition: field.cpp:69
float local_light_override() const
Definition: field.cpp:74
float light_transparency(const tripoint &p) const
Definition: lightmap.cpp:631
void apply_directional_light(const tripoint &p, int direction, float luminance)
Definition: lightmap.cpp:1511
void build_sunlight_cache(int pzlev)
Definition: lightmap.cpp:220
void add_light_from_items(const tripoint &p, item_stack::iterator begin, item_stack::iterator end)
Definition: lightmap.cpp:63
void apply_character_light(Character &p)
Definition: lightmap.cpp:198
Definition: npc.h:781
units::angle dir() const
Definition: tileray.cpp:74
std::vector< vehicle_part * > lights(bool active=false)
Get all vehicle lights (excluding any that are destroyed)
Definition: vehicle.cpp:4642
vehicle_stack get_items(int part) const
Definition: vehicle.cpp:5468
bool once_every(const time_duration &event_frequency)
Predicate to handle rate-limiting.
Definition: calendar.cpp:490
@ VPFLAG_CONE_LIGHT
Definition: veh_type.h:35
@ VPFLAG_CIRCLE_LIGHT
Definition: veh_type.h:38
@ VPFLAG_CARGO
Definition: veh_type.h:62
@ VPFLAG_EVENTURN
Definition: veh_type.h:33
@ VPFLAG_WIDE_CONE_LIGHT
Definition: veh_type.h:36
@ VPFLAG_ODDTURN
Definition: veh_type.h:34
@ VPFLAG_HALF_CIRCLE_LIGHT
Definition: veh_type.h:37

References add_light_from_items(), add_light_source(), apply_character_light(), apply_directional_light(), apply_light_arc(), apply_light_source(), item_stack::begin(), build_sunlight_cache(), clamp(), default_, tileray::dir(), effect_onfire, item_stack::end(), vehicle::face, level_cache::floor_cache, furniture, g, vehicle::get_all_parts(), get_cache(), vehicle::get_items(), get_player_character(), get_submap_at_grid(), get_vehicles(), vehicle::global_part_pos3(), has_items(), i_at(), inbounds(), field_entry::light_emitted(), light_transparency(), LIGHT_TRANSPARENCY_SOLID, lightmap_boundaries, LIGHTMAP_CACHE_X, LIGHTMAP_CACHE_Y, vehicle::lights(), LIT, field_entry::local_light_override(), M_SQRT2, my_MAPSIZE, NE, NW, calendar::once_every(), OVERMAP_DEPTH, points_in_rectangle(), SE, SEEX, SEEY, coords::sm, SW, sx, sy, terrain, update_light_quadrants(), VPFLAG_CARGO, VPFLAG_CIRCLE_LIGHT, VPFLAG_CONE_LIGHT, VPFLAG_EVENTURN, VPFLAG_HALF_CIRCLE_LIGHT, VPFLAG_ODDTURN, VPFLAG_WIDE_CONE_LIGHT, point::x, tripoint::x, tripoint::xy(), point::y, and tripoint::y.

Referenced by build_map_cache().

◆ get_abs_sub()

◆ get_active_items_in_radius() [1/2]

std::list< item_location > map::get_active_items_in_radius ( const tripoint center,
int  radius 
) const

Definition at line 8631 of file map.cpp.

8633{
8635}
std::list< item_location > get_active_items_in_radius(const tripoint &center, int radius) const
Definition: map.cpp:8631

References center, get_active_items_in_radius(), and none.

Referenced by npc::find_corpse_to_pulp(), npc::find_dangerous_explosives(), and get_active_items_in_radius().

◆ get_active_items_in_radius() [2/2]

std::list< item_location > map::get_active_items_in_radius ( const tripoint center,
int  radius,
special_item_type  type 
) const

Definition at line 8637 of file map.cpp.

8639{
8640 std::list<item_location> result;
8641
8642 const point minp( center.xy() + point( -radius, -radius ) );
8643 const point maxp( center.xy() + point( radius, radius ) );
8644
8645 const point ming( std::max( minp.x / SEEX, 0 ),
8646 std::max( minp.y / SEEY, 0 ) );
8647 const point maxg( std::min( maxp.x / SEEX, my_MAPSIZE - 1 ),
8648 std::min( maxp.y / SEEY, my_MAPSIZE - 1 ) );
8649
8650 for( const tripoint &abs_submap_loc : submaps_with_active_items ) {
8651 const tripoint submap_loc{ -abs_sub.xy() + abs_submap_loc };
8652 if( submap_loc.x < ming.x || submap_loc.y < ming.y ||
8653 submap_loc.x > maxg.x || submap_loc.y > maxg.y ) {
8654 continue;
8655 }
8656 const point sm_offset( submap_loc.x * SEEX, submap_loc.y * SEEY );
8657
8658 submap *sm = get_submap_at_grid( submap_loc );
8659 std::vector<item_reference> items = type == special_item_type::none ? sm->active_items.get() :
8660 sm->active_items.get_special( type );
8661 for( const auto &elem : items ) {
8662 const tripoint pos( sm_offset + elem.location, submap_loc.z );
8663
8664 if( rl_dist( pos, center ) > radius ) {
8665 continue;
8666 }
8667
8668 if( elem.item_ref ) {
8669 result.emplace_back( map_cursor( pos ), elem.item_ref.get() );
8670 }
8671 }
8672 }
8673
8674 return result;
8675}

References abs_sub, center, get_submap_at_grid(), my_MAPSIZE, none, rl_dist(), SEEX, SEEY, coords::sm, submaps_with_active_items, type, point::x, tripoint::xy(), and point::y.

◆ get_cache()

◆ get_cache_ref()

◆ get_creatures_in_radius()

std::list< Creature * > map::get_creatures_in_radius ( const tripoint center,
size_t  radius,
size_t  radiusz = 0 
)

returns creatures in specified radius

Definition at line 8691 of file map.cpp.

8693{
8694 std::list<Creature *> creatures;
8695 for( const auto &loc : points_in_radius( center, radius, radiusz ) ) {
8696 Creature *tmp_critter = g->critter_at( loc );
8697 if( tmp_critter != nullptr ) {
8698 creatures.push_back( tmp_critter );
8699 }
8700
8701 }
8702 return creatures;
8703}

References center, g, and points_in_radius().

◆ get_dir_circle()

std::vector< tripoint > map::get_dir_circle ( const tripoint f,
const tripoint t 
) const

Calculate next search points surrounding the current position.

Points closer to the target come first. This method leads to straighter lines and prevents weird looking movements away from the target.

Definition at line 6560 of file map.cpp.

6561{
6562 std::vector<tripoint> circle;
6563 circle.resize( 8 );
6564
6565 // The line below can be crazy expensive - we only take the FIRST point of it
6566 const std::vector<tripoint> line = line_to( f, t, 0, 0 );
6567 const std::vector<tripoint> spiral = closest_points_first( f, 1 );
6568 const std::vector<int> pos_index {1, 2, 4, 6, 8, 7, 5, 3};
6569
6570 // All possible constellations (closest_points_first goes clockwise)
6571 // 753 531 312 124 246 468 687 875
6572 // 8 1 7 2 5 4 3 6 1 8 2 7 4 5 6 3
6573 // 642 864 786 578 357 135 213 421
6574
6575 size_t pos_offset = 0;
6576 for( size_t i = 1; i < spiral.size(); i++ ) {
6577 if( spiral[i] == line[0] ) {
6578 pos_offset = i - 1;
6579 break;
6580 }
6581 }
6582
6583 for( size_t i = 1; i < spiral.size(); i++ ) {
6584 if( pos_offset >= pos_index.size() ) {
6585 pos_offset = 0;
6586 }
6587
6588 circle[pos_index[pos_offset++] - 1] = spiral[i];
6589 }
6590
6591 return circle;
6592}
void circle(map *m, const ter_id &type, double x, double y, double rad)
Definition: mapgen.cpp:6499

References circle(), closest_points_first(), line(), and line_to().

Referenced by npc::move_to().

◆ get_field() [1/2]

field & map::get_field ( const tripoint p)
private

Definition at line 8467 of file map.cpp.

8468{
8469 return field_at( p );
8470}

References field_at().

◆ get_field() [2/2]

field_entry * map::get_field ( const tripoint p,
const field_type_id type 
)

◆ get_field_age()

time_duration map::get_field_age ( const tripoint p,
const field_type_id type 
) const

Get the age of a field entry (field_entry::age), if there is no field of that type, returns -1_turns.

Definition at line 5361 of file map.cpp.

5362{
5363 auto field_ptr = field_at( p ).find_field( type );
5364 return field_ptr == nullptr ? -1_turns : field_ptr->get_field_age();
5365}

References field_at(), field::find_field(), field_entry::get_field_age(), and type.

Referenced by game::grabbed_furn_move(), try_fuel_fire(), and game::walk_move().

◆ get_field_intensity()

int map::get_field_intensity ( const tripoint p,
const field_type_id type 
) const

Get the intensity of a field entry (field_entry::intensity), if there is no field of that type, returns 0.

Definition at line 5367 of file map.cpp.

5368{
5369 auto field_ptr = field_at( p ).find_field( type );
5370 return ( field_ptr == nullptr ? 0 : field_ptr->get_field_intensity() );
5371}

References field_at(), field::find_field(), and type.

Referenced by Character::base_comfort_value(), game::grabbed_furn_move(), is_flammable(), propagate_field(), fungal_effects::spread_fungus_one_tile(), and game::walk_move().

◆ get_furn_field_locations()

const std::vector< tripoint > & map::get_furn_field_locations ( ) const

Definition at line 7746 of file map.cpp.

7747{
7748 return field_furn_locs;
7749}

References field_furn_locs.

Referenced by game::do_turn().

◆ get_furn_transforms_into()

furn_id map::get_furn_transforms_into ( const tripoint p) const

Definition at line 1612 of file map.cpp.

1613{
1614 return furn( p ).obj().transforms_into.id();
1615}
furn_str_id transforms_into
Definition: mapdata.h:499

References furn(), string_id< T >::id(), int_id< T >::obj(), and furn_t::transforms_into.

◆ get_harvest()

const harvest_id & map::get_harvest ( const tripoint p) const

Returns the full harvest list, for spawning.

Definition at line 1564 of file map.cpp.

1565{
1566 const auto furn_here = furn( pos );
1567 if( furn_here->examine != iexamine::none ) {
1568 // Note: if furniture can be examined, the terrain can NOT (until furniture is removed)
1569 if( furn_here->has_flag( TFLAG_HARVESTED ) ) {
1570 return harvest_id::NULL_ID();
1571 }
1572
1573 return furn_here->get_harvest();
1574 }
1575
1576 const auto ter_here = ter( pos );
1577 if( ter_here->has_flag( TFLAG_HARVESTED ) ) {
1578 return harvest_id::NULL_ID();
1579 }
1580
1581 return ter_here->get_harvest();
1582}
static const string_id< harvest_list > & NULL_ID()
Returns a null id whose string_id<T>::is_null() must always return true.
@ TFLAG_HARVESTED
Definition: mapdata.h:303

References furn(), iexamine::none(), string_id< harvest_list >::NULL_ID(), wrapped_vehicle::pos, ter(), and TFLAG_HARVESTED.

Referenced by harvest_common(), and is_harvestable().

◆ get_harvest_names()

const std::set< std::string > & map::get_harvest_names ( const tripoint p) const

Returns names of the items that would be dropped.

Definition at line 1584 of file map.cpp.

1585{
1586 static const std::set<std::string> null_harvest_names = {};
1587 const auto furn_here = furn( pos );
1588 if( furn_here->examine != iexamine::none ) {
1589 if( furn_here->has_flag( TFLAG_HARVESTED ) ) {
1590 return null_harvest_names;
1591 }
1592
1593 return furn_here->get_harvest_names();
1594 }
1595
1596 const auto ter_here = ter( pos );
1597 if( ter_here->has_flag( TFLAG_HARVESTED ) ) {
1598 return null_harvest_names;
1599 }
1600
1601 return ter_here->get_harvest_names();
1602}

References furn(), iexamine::none(), wrapped_vehicle::pos, ter(), and TFLAG_HARVESTED.

Referenced by npc::find_item().

◆ get_known_connections()

uint8_t map::get_known_connections ( const tripoint p,
int  connect_group,
const std::map< tripoint, ter_id > &  override = {} 
) const

Definition at line 1510 of file map.cpp.

1512{
1513 auto &ch = access_cache( p.z );
1514 uint8_t val = 0;
1515 std::function<bool( const tripoint & )> is_memorized;
1516#ifdef TILES
1517 if( use_tiles ) {
1518 is_memorized =
1519 [&]( const tripoint & q ) {
1520 return !g->u.get_memorized_tile( getabs( q ) ).tile.empty();
1521 };
1522 } else {
1523#endif
1524 is_memorized =
1525 [&]( const tripoint & q ) {
1526 return g->u.get_memorized_symbol( getabs( q ) );
1527 };
1528#ifdef TILES
1529 }
1530#endif
1531
1532 const bool overridden = override.find( p ) != override.end();
1533 const bool is_transparent = ch.transparency_cache[p.x][p.y] > LIGHT_TRANSPARENCY_SOLID;
1534
1535 // populate connection information
1536 for( int i = 0; i < 4; ++i ) {
1537 tripoint neighbour = p + offsets[i];
1538 if( !inbounds( neighbour ) ) {
1539 continue;
1540 }
1541 const auto neighbour_override = override.find( neighbour );
1542 const bool neighbour_overridden = neighbour_override != override.end();
1543 // if there's some non-memory terrain to show at the neighboring tile
1544 const bool may_connect = neighbour_overridden ||
1545 get_visibility( ch.visibility_cache[neighbour.x][neighbour.y],
1547 // or if an actual center tile is transparent or next to a memorized tile
1548 ( !overridden && ( is_transparent || is_memorized( neighbour ) ) );
1549 if( may_connect ) {
1550 const ter_t &neighbour_terrain = neighbour_overridden ?
1551 neighbour_override->second.obj() : ter( neighbour ).obj();
1552 if( neighbour_terrain.connects_to( connect_group ) ) {
1553 val += 1 << i;
1554 }
1555 }
1556 }
1557
1558 return val;
1559}
bool use_tiles
Use tiles for display.
bool is_transparent(const tripoint &p) const
Returns whether the tile at p is transparent(you can look past it).
Definition: lightmap.cpp:626
level_cache & access_cache(int zlev)
Definition: map.cpp:8705
static constexpr std::array< point, 4 > offsets
Definition: point.h:371
bool connects_to(int test_connect_group) const
Definition: mapdata.h:431

References access_cache(), map_data_common_t::connects_to(), g, get_visibility(), get_visibility_variables_cache(), getabs(), inbounds(), is_transparent(), LIGHT_TRANSPARENCY_SOLID, int_id< T >::obj(), offsets, ter(), use_tiles, VIS_CLEAR, tripoint::x, tripoint::y, and tripoint::z.

Referenced by determine_wall_corner().

◆ get_neighbors()

std::array< std::pair< tripoint, maptile >, 8 > map::get_neighbors ( const tripoint p)
private

Definition at line 190 of file map_field.cpp.

191{
192 // Find out which edges are in the bubble
193 // Where possible, do just one bounds check for all the neighbors
194 const bool west = p.x > 0;
195 const bool north = p.y > 0;
196 const bool east = p.x < SEEX * my_MAPSIZE - 1;
197 const bool south = p.y < SEEY * my_MAPSIZE - 1;
198 return std::array< std::pair<tripoint, maptile>, 8 > { {
199 maptile_has_bounds( p + eight_horizontal_neighbors[0], west &&north ),
201 maptile_has_bounds( p + eight_horizontal_neighbors[2], east &&north ),
204 maptile_has_bounds( p + eight_horizontal_neighbors[5], west &&south ),
206 maptile_has_bounds( p + eight_horizontal_neighbors[7], east &&south ),
207 }
208 };
209}
std::pair< tripoint, maptile > maptile_has_bounds(const tripoint &p, bool bounds_checked)
Definition: map_field.cpp:180
static const std::array< tripoint, 8 > eight_horizontal_neighbors
Definition: point.h:389

References eight_horizontal_neighbors, maptile_has_bounds(), my_MAPSIZE, SEEX, SEEY, tripoint::x, and tripoint::y.

Referenced by process_fields_in_submap(), and spread_gas().

◆ get_nonant() [1/2]

size_t map::get_nonant ( const point gridp) const
inlineprotected

Definition at line 1881 of file map.h.

1881 {
1882 return get_nonant( { gridp, abs_sub.z } );
1883 }

References abs_sub, get_nonant(), and tripoint::z.

◆ get_nonant() [2/2]

size_t map::get_nonant ( const tripoint gridp) const
protected

Get the index of a submap pointer in the grid given by grid coordinates.

The grid coordinates must be valid: 0 <= x < my_MAPSIZE, same for y. Version with z-levels checks for z between -OVERMAP_DEPTH and OVERMAP_HEIGHT

Definition at line 8323 of file map.cpp.

8324{
8325 // There used to be a bounds check here
8326 // But this function is called a lot, so push it up if needed
8327 if( zlevels ) {
8328 const int indexz = gridp.z + OVERMAP_HEIGHT; // Can't be lower than 0
8329 return indexz + ( gridp.x + gridp.y * my_MAPSIZE ) * OVERMAP_LAYERS;
8330 } else {
8331 return gridp.x + gridp.y * my_MAPSIZE;
8332 }
8333}

References my_MAPSIZE, OVERMAP_HEIGHT, OVERMAP_LAYERS, tripoint::x, tripoint::y, tripoint::z, and zlevels.

Referenced by copy_grid(), fake_map::fake_map(), generate(), get_nonant(), get_submap_at_grid(), loadn(), and saven().

◆ get_pathfinding_cache()

pathfinding_cache & map::get_pathfinding_cache ( int  zlev) const
private

Definition at line 8756 of file map.cpp.

8757{
8758 return *pathfinding_caches[zlev + OVERMAP_DEPTH];
8759}

References OVERMAP_DEPTH, and pathfinding_caches.

Referenced by get_pathfinding_cache_ref(), set_pathfinding_cache_dirty(), and update_pathfinding_cache().

◆ get_pathfinding_cache_ref()

const pathfinding_cache & map::get_pathfinding_cache_ref ( int  zlev) const

Definition at line 8768 of file map.cpp.

8769{
8770 if( !inbounds_z( zlev ) ) {
8771 debugmsg( "Tried to get pathfinding cache for out of bounds z-level %d", zlev );
8773 }
8774 auto &cache = get_pathfinding_cache( zlev );
8775 if( cache.dirty ) {
8777 }
8778
8779 return cache;
8780}
void update_pathfinding_cache(int zlev) const
Definition: map.cpp:8782
bool inbounds_z(const int z) const
Definition: map.h:1673
pathfinding_cache & get_pathfinding_cache(int zlev) const
Definition: map.cpp:8756

References debugmsg, get_pathfinding_cache(), inbounds_z(), OVERMAP_DEPTH, pathfinding_caches, and update_pathfinding_cache().

Referenced by route(), and vertical_move_destination().

◆ get_radiation()

int map::get_radiation ( const tripoint p) const

Definition at line 4023 of file map.cpp.

4024{
4025 if( !inbounds( p ) ) {
4026 return 0;
4027 }
4028
4029 point l;
4030 submap *const current_submap = get_submap_at( p, l );
4031
4032 return current_submap->get_radiation( l );
4033}

References submap::get_radiation(), get_submap_at(), and inbounds().

Referenced by computer_session::action_geiger(), computer_session::action_irradiator(), check_art_charge_req(), editmap::draw_main_ui_overlay(), and rad_scorch().

◆ get_roof()

ter_id map::get_roof ( const tripoint p,
bool  allow_air 
) const
private

Definition at line 3094 of file map.cpp.

3095{
3096 // This function should not be called from the 2D mode
3097 // Just use t_dirt instead
3098 assert( zlevels );
3099
3100 if( p.z <= -OVERMAP_DEPTH ) {
3101 // Could be magma/"void" instead
3102 return t_rock_floor;
3103 }
3104
3105 const auto &ter_there = ter( p ).obj();
3106 const auto &roof = ter_there.roof;
3107 if( !roof ) {
3108 // No roof
3109 if( !allow_air ) {
3110 // TODO: Biomes? By setting? Forbid and treat as bug?
3111 if( p.z < 0 ) {
3112 return t_rock_floor_no_roof;
3113 }
3114
3115 return t_dirt;
3116 }
3117
3118 return t_open_air;
3119 }
3120
3121 ter_id new_ter = roof.id();
3122 if( new_ter == t_null ) {
3123 debugmsg( "map::get_new_floor: %d,%d,%d has invalid roof type %s",
3124 p.x, p.y, p.z, roof.c_str() );
3125 return t_dirt;
3126 }
3127
3128 if( p.z == -1 && new_ter == t_rock_floor ) {
3129 // HACK: A hack to work around not having a "solid earth" tile
3130 new_ter = t_dirt;
3131 }
3132
3133 return new_ter;
3134}
static const ter_str_id t_rock_floor_no_roof("t_rock_floor_no_roof")

References debugmsg, int_id< T >::id(), int_id< T >::obj(), OVERMAP_DEPTH, ter_t::roof, t_dirt, t_null, t_open_air, t_rock_floor, t_rock_floor_no_roof, ter(), tripoint::x, tripoint::y, tripoint::z, and zlevels.

Referenced by bash_ter_furn(), and bash_ter_success().

◆ get_signage()

std::string map::get_signage ( const tripoint p) const

Definition at line 3989 of file map.cpp.

3990{
3991 if( !inbounds( p ) ) {
3992 return "";
3993 }
3994
3995 point l;
3996 submap *const current_submap = get_submap_at( p, l );
3997
3998 return current_submap->get_signage( l );
3999}
std::string get_signage(const point &p) const
Definition: submap.cpp:126

References submap::get_signage(), get_submap_at(), and inbounds().

Referenced by game::extended_description(), game::place_player(), game::print_terrain_info(), and iexamine::sign().

◆ get_submap_at() [1/4]

submap * map::get_submap_at ( const point p) const
inlineprivate

Definition at line 1853 of file map.h.

1853 {
1854 return get_submap_at( tripoint( p, abs_sub.z ) );
1855 }

References abs_sub, get_submap_at(), and tripoint::z.

◆ get_submap_at() [2/4]

submap * map::get_submap_at ( const point p,
point offset_p 
) const
inlineprivate

Definition at line 1862 of file map.h.

1862 {
1863 return get_submap_at( { p, abs_sub.z }, offset_p );
1864 }

References abs_sub, get_submap_at(), and tripoint::z.

◆ get_submap_at() [3/4]

◆ get_submap_at() [4/4]

submap * map::get_submap_at ( const tripoint p,
point offset_p 
) const
private

Get the submap pointer containing the specified position within the reality bubble.

The same as other get_submap_at, (p) must be valid (inbounds). Also writes the position within the submap to offset_p

Definition at line 8311 of file map.cpp.

8312{
8313 offset_p.x = p.x % SEEX;
8314 offset_p.y = p.y % SEEY;
8315 return get_submap_at( p );
8316}

References get_submap_at(), SEEX, SEEY, point::x, tripoint::x, point::y, and tripoint::y.

◆ get_submap_at_grid() [1/2]

◆ get_submap_at_grid() [2/2]

submap * map::get_submap_at_grid ( const tripoint gridp) const
private

Definition at line 8318 of file map.cpp.

8319{
8320 return getsubmap( get_nonant( gridp ) );
8321}

References get_nonant(), and getsubmap().

◆ get_submaps_with_active_items()

const std::set< tripoint > & map::get_submaps_with_active_items ( ) const
inline

Definition at line 2054 of file map.h.

2054 {
2056 }

References submaps_with_active_items.

◆ get_temperature()

int map::get_temperature ( const tripoint p) const

Definition at line 4060 of file map.cpp.

4061{
4062 if( !inbounds( p ) ) {
4063 return 0;
4064 }
4065
4066 return get_submap_at( p )->get_temperature();
4067}
int get_temperature() const
Definition: submap.h:194

References get_submap_at(), submap::get_temperature(), and inbounds().

◆ get_ter_transforms_into()

ter_id map::get_ter_transforms_into ( const tripoint p) const

Definition at line 1607 of file map.cpp.

1608{
1609 return ter( p ).obj().transforms_into.id();
1610}
ter_str_id transforms_into
Definition: mapdata.h:466

References string_id< T >::id(), int_id< T >::obj(), ter(), and ter_t::transforms_into.

Referenced by iexamine::harvest_ter(), iexamine::harvest_ter_nectar(), and iexamine::tree_hickory().

◆ get_vehicle_zones()

std::vector< zone_data * > map::get_vehicle_zones ( int  zlev)

Definition at line 939 of file map.cpp.

940{
941 std::vector<zone_data *> veh_zones;
942 bool rebuild = false;
943 for( auto veh : get_cache( zlev ).zone_vehicles ) {
944 if( veh->refresh_zones() ) {
945 rebuild = true;
946 }
947 for( auto &zone : veh->loot_zones ) {
948 veh_zones.emplace_back( &zone.second );
949 }
950 }
951 if( rebuild ) {
953 }
954 return veh_zones;
955}
static zone_manager & get_manager()
Definition: clzones.cpp:126
void cache_vzones()
Definition: clzones.cpp:624

References zone_manager::cache_vzones(), get_cache(), and zone_manager::get_manager().

Referenced by zone_manager::cache_vzones(), zone_manager::get_bottom_zone(), zone_manager::get_zone_at(), and zone_manager::get_zones().

◆ get_vehicles() [1/2]

◆ get_vehicles() [2/2]

VehicleList map::get_vehicles ( const tripoint start,
const tripoint end 
)

Definition at line 980 of file map.cpp.

981{
982 const int chunk_sx = std::max( 0, ( start.x / SEEX ) - 1 );
983 const int chunk_ex = std::min( my_MAPSIZE - 1, ( end.x / SEEX ) + 1 );
984 const int chunk_sy = std::max( 0, ( start.y / SEEY ) - 1 );
985 const int chunk_ey = std::min( my_MAPSIZE - 1, ( end.y / SEEY ) + 1 );
986 const int chunk_sz = start.z;
987 const int chunk_ez = end.z;
988 VehicleList vehs;
989
990 for( int cx = chunk_sx; cx <= chunk_ex; ++cx ) {
991 for( int cy = chunk_sy; cy <= chunk_ey; ++cy ) {
992 for( int cz = chunk_sz; cz <= chunk_ez; ++cz ) {
993 submap *current_submap = get_submap_at_grid( { cx, cy, cz } );
994 for( const auto &elem : current_submap->vehicles ) {
995 // Ensure the vehicle z-position is correct
996 elem->sm_pos.z = cz;
998 w.v = elem.get();
999 w.pos = w.v->global_pos3();
1000 vehs.push_back( w );
1001 }
1002 }
1003 }
1004 }
1005
1006 return vehs;
1007}
tripoint pos
Definition: map.h:81
vehicle * v
Definition: map.h:82

References get_submap_at_grid(), vehicle::global_pos3(), my_MAPSIZE, wrapped_vehicle::pos, SEEX, SEEY, wrapped_vehicle::v, submap::vehicles, tripoint::x, tripoint::y, and tripoint::z.

◆ get_visibility()

visibility_type map::get_visibility ( lit_level  ll,
const visibility_variables cache 
) const

Definition at line 5650 of file map.cpp.

5652{
5653 switch( ll ) {
5654 case lit_level::DARK:
5655 // can't see this square at all
5656 if( cache.u_is_boomered ) {
5657 return VIS_BOOMER_DARK;
5658 } else {
5659 return VIS_DARK;
5660 }
5662 // can only tell that this square is bright
5663 if( cache.u_is_boomered ) {
5664 return VIS_BOOMER;
5665 } else {
5666 return VIS_LIT;
5667 }
5668
5669 case lit_level::LOW:
5670 // low light, square visible in monochrome
5671 case lit_level::LIT:
5672 // normal light
5673 case lit_level::BRIGHT:
5674 // bright light
5675 return VIS_CLEAR;
5676 case lit_level::BLANK:
5678 return VIS_HIDDEN;
5679 }
5680 return VIS_HIDDEN;
5681}
bool u_is_boomered
Definition: map.h:124

References BLANK, BRIGHT, BRIGHT_ONLY, DARK, LIT, LOW, MEMORIZED, visibility_variables::u_is_boomered, VIS_BOOMER, VIS_BOOMER_DARK, VIS_CLEAR, VIS_DARK, VIS_HIDDEN, and VIS_LIT.

Referenced by draw(), game::draw_look_around_cursor(), generate_weather_anim_frame(), get_known_connections(), and game::print_all_tile_info().

◆ get_visibility_variables_cache()

const visibility_variables & map::get_visibility_variables_cache ( ) const

Definition at line 5645 of file map.cpp.

5646{
5648}
visibility_variables visibility_variables_cache
Definition: map.h:2033

References visibility_variables_cache.

Referenced by draw(), generate_weather_anim_frame(), get_known_connections(), game::look_around(), live_view::show(), and editmap::update_view_with_help().

◆ get_wind_blockers()

std::tuple< maptile, maptile, maptile > map::get_wind_blockers ( const int &  winddirection,
const tripoint pos 
)

Definition at line 1894 of file map_field.cpp.

1896{
1897 static const std::array<std::pair<int, std::tuple< point, point, point >>, 9> outputs = {{
1898 { 330, std::make_tuple( point_east, point_north_east, point_south_east ) },
1899 { 301, std::make_tuple( point_south_east, point_east, point_south ) },
1900 { 240, std::make_tuple( point_south, point_south_west, point_south_east ) },
1901 { 211, std::make_tuple( point_south_west, point_west, point_south ) },
1902 { 150, std::make_tuple( point_west, point_north_west, point_south_west ) },
1903 { 121, std::make_tuple( point_north_west, point_north, point_west ) },
1904 { 60, std::make_tuple( point_north, point_north_west, point_north_east ) },
1905 { 31, std::make_tuple( point_north_east, point_east, point_north ) },
1906 { 0, std::make_tuple( point_east, point_north_east, point_south_east ) }
1907 }
1908 };
1909
1910 tripoint removepoint;
1911 tripoint removepoint2;
1912 tripoint removepoint3;
1913 for( const std::pair<int, std::tuple< point, point, point >> &val : outputs ) {
1914 if( winddirection >= val.first ) {
1915 removepoint = pos + std::get<0>( val.second );
1916 removepoint2 = pos + std::get<1>( val.second );
1917 removepoint3 = pos + std::get<2>( val.second );
1918 break;
1919 }
1920 }
1921
1922 const maptile remove_tile = maptile_at( removepoint );
1923 const maptile remove_tile2 = maptile_at( removepoint2 );
1924 const maptile remove_tile3 = maptile_at( removepoint3 );
1925 return std::make_tuple( remove_tile, remove_tile2, remove_tile3 );
1926}

References maptile_at(), point_east, point_north, point_north_east, point_north_west, point_south, point_south_east, point_south_west, and point_west.

Referenced by spread_gas().

◆ getabs() [1/2]

point map::getabs ( const point p) const
inline

Definition at line 1658 of file map.h.

1658 {
1659 return getabs( tripoint( p, abs_sub.z ) ).xy();
1660 }

References abs_sub, getabs(), tripoint::xy(), and tripoint::z.

◆ getabs() [2/2]

tripoint map::getabs ( const tripoint p) const

Translates local (to this map) coordinates of a square to global absolute coordinates.

Coordinates is in the system that is used by the ter/furn/i_at functions. Output is in the same scale, but in global system.

Definition at line 8261 of file map.cpp.

8262{
8263 return sm_to_ms_copy( abs_sub.xy() ) + p;
8264}

References abs_sub, sm_to_ms_copy(), and tripoint::xy().

Referenced by activity_on_turn_move_loot(), add_basecamp_storage_to_loot_zone_list(), add_item(), Character::add_known_trap(), jmapgen_zone::apply(), are_requirements_nearby(), game::autopilot_vehicles(), talk_function::basecamp_mission(), bash_ter_furn(), iexamine::bulletin_board(), butcher_corpse_activity(), can_do_activity_there(), iexamine::cardreader(), vehicle::autodrive_controller::check_drivable(), game::check_near_zone(), game::check_zone(), chop_plank_activity(), chop_tree_activity(), complete_construction(), construction_activity(), game::control_vehicle(), activity_handlers::repair_activity_hack::anonymous_namespace{activity_handlers.cpp}::discharge_real_power_source(), npc::do_pulp(), construct::done_digormine_stair(), construct::done_mine_upstair(), draw_maptile(), editmap::edit_mapgen(), iexamine::elevator(), fill_funnels(), find_auto_consume(), game::find_or_make_stairs(), find_refuel_spot_zone(), find_valid_teleporters_omt(), activity_handlers::forage_finish(), inventory::form_from_map(), furn_set(), generic_multi_activity_check_requirement(), generic_multi_activity_do(), generic_multi_activity_handler(), generic_multi_activity_locations(), activity_handlers::repair_activity_hack::anonymous_namespace{activity_handlers.cpp}::get_fake_tool(), get_known_connections(), zone_manager::get_point_set_loot(), getabs(), Character::global_square_location(), npc::go_to_omt_destination(), good_fishing_spot(), game::grabbed_furn_move(), grow_plant(), npc::guard_current_pos(), Character::knows_trap(), mine_activity(), npc::move(), perform_zone_activity_turn(), place_construction(), game::place_player(), basecamp::place_results(), game::place_vehicle_nearby(), iexamine::plant_seed(), game::pre_print_all_tile_info(), sounds::process_sounds(), plot_options::query_seed(), npc::reach_omt_destination(), remove_submap_turrets(), requirements_map(), zone_manager::rotate_zones(), conditional_t< T >::set_is_outside(), target_ui::set_last_target(), shoot(), iexamine::shrub_wildveggies(), smash(), spawn_monsters_submap_group(), debug_menu::spawn_nested_mapgen(), spread_gas(), ter_set(), tidy_activity(), vehicle::total_wind_epower_w(), translate_radius(), iexamine::trap(), update_suspension_cache(), use_charges_from_furn(), iexamine::use_furn_fake_item(), basecamp::validate_sort_points(), vehicle_activity(), vertical_move_destination(), iuse::weather_tool(), npc::worker_downtime(), and game::zones_manager().

◆ getlocal() [1/2]

point map::getlocal ( const point p) const
inline

Definition at line 1665 of file map.h.

1665 {
1666 return getlocal( tripoint( p, abs_sub.z ) ).xy();
1667 }

References abs_sub, getlocal(), tripoint::xy(), and tripoint::z.

◆ getlocal() [2/2]

tripoint map::getlocal ( const tripoint p) const

Inverse of getabs.

Definition at line 8266 of file map.cpp.

8267{
8268 return p - sm_to_ms_copy( abs_sub.xy() );
8269}

References abs_sub, sm_to_ms_copy(), and tripoint::xy().

Referenced by basecamp::abandon_camp(), activity_on_turn_move_loot(), zone_manager::add(), add_basecamp_storage_to_loot_zone_list(), grid_furn_transform_queue::apply(), talk_function::basecamp_mission(), activity_handlers::build_do_turn(), can_do_activity_there(), Character::check_outbounds_activity(), activity_handlers::chop_logs_finish(), activity_handlers::chop_planks_finish(), activity_handlers::chop_tree_do_turn(), activity_handlers::chop_tree_finish(), activity_handlers::churn_finish(), cleanup_tiles(), complete_construction(), veh_interact::complete_vehicle(), vehicle::autodrive_controller::compute_obstacles(), basecamp_action_components::consume_components(), deregister_vehicle_zone(), basecamp::distribute_food(), construct::done_digormine_stair(), construct::done_mine_upstair(), editmap::edit_mapgen(), npc::execute_action(), fetch_activity(), find_auto_consume(), game::find_or_make_stairs(), find_refuel_spot_zone(), activity_handlers::forage_finish(), basecamp::form_crafting_inventory(), inventory::form_from_zone(), generic_multi_activity_check_requirement(), generic_multi_activity_handler(), generic_multi_activity_locations(), zone_manager::get_point_set_loot(), getlocal(), npc::go_to_omt_destination(), npc::good_escape_direction(), Character::has_destination_activity(), activity_handlers::jackhammer_do_turn(), activity_handlers::jackhammer_finish(), activity_handlers::milk_finish(), npc::move(), npc::move_to(), map_cursor::operator tripoint(), perform_zone_activity_turn(), activity_handlers::pickaxe_do_turn(), activity_handlers::pickaxe_finish(), teleporter_list::place_avatar_overmap(), basecamp::place_results(), game::place_vehicle_nearby(), activity_handlers::plant_seed_finish(), vehicle_part::properties_to_item(), activity_handlers::pulp_do_turn(), plot_options::query_seed(), npc::reach_omt_destination(), target_ui::recalc_aim_turning_penalty(), npc::regen_ai_cache(), requirements_map(), zone_manager::revert_vzones(), rotate(), zone_manager::rotate_zones(), activity_handlers::shear_finish(), debug_menu::spawn_nested_mapgen(), tidy_activity(), activity_handlers::travel_do_turn(), target_ui::try_reacquire_target(), update_suspension_cache(), basecamp::validate_sort_points(), activity_handlers::vehicle_finish(), vertical_move_destination(), npc::worker_downtime(), and game::zones_manager().

◆ getmapsize()

int map::getmapsize ( ) const
inline

Definition at line 1682 of file map.h.

1682 {
1683 return my_MAPSIZE;
1684 }

References my_MAPSIZE.

Referenced by distribution_grid_tracker::load(), editmap::mapgen_preview(), and points_in_range().

◆ getsubmap()

submap * map::getsubmap ( size_t  grididx) const
private

Get the submap pointer with given index in grid, the index must be valid!

Definition at line 8281 of file map.cpp.

8282{
8283 if( grididx >= grid.size() ) {
8284 debugmsg( "Tried to access invalid grid index %d. Grid size: %d", grididx, grid.size() );
8285 return nullptr;
8286 }
8287 return grid[grididx];
8288}

References debugmsg, and grid.

Referenced by generate(), get_submap_at_grid(), and saven().

◆ graffiti_at()

const std::string & map::graffiti_at ( const tripoint p) const

Definition at line 7822 of file map.cpp.

7823{
7824 if( !inbounds( p ) ) {
7825 static const std::string empty_string;
7826 return empty_string;
7827 }
7828 point l;
7829 submap *const current_submap = get_submap_at( p, l );
7830 return current_submap->get_graffiti( l );
7831}
const std::string & get_graffiti(const point &p) const
Definition: submap.cpp:88

References submap::get_graffiti(), get_submap_at(), and inbounds().

Referenced by advanced_inv_area::init(), game::place_player(), game::print_graffiti_info(), and editmap::update_view_with_help().

◆ grow_plant()

void map::grow_plant ( const tripoint p)
protected

Try to grow a harvestable plant to the next stage(s).

Definition at line 7151 of file map.cpp.

7152{
7153 const auto &furn = this->furn( p ).obj();
7154 if( !furn.has_flag( "PLANT" ) ) {
7155 return;
7156 }
7157 // Can't use item_stack::only_item() since there might be fertilizer
7158 map_stack items = i_at( p );
7159 map_stack::iterator seed = std::find_if( items.begin(), items.end(), []( const item & it ) {
7160 return it.is_seed();
7161 } );
7162
7163 if( seed == items.end() ) {
7164 // No seed there anymore, we don't know what kind of plant it was.
7165 // TODO: Fix point types
7166 const oter_id ot = overmap_buffer.ter( project_to<coords::omt>( tripoint_abs_ms( getabs( p ) ) ) );
7167 dbg( DL::Error ) << "a planted item at " << p
7168 << " (within overmap terrain " << ot.id().str() << ") has no seed data";
7169 i_clear( p );
7170 furn_set( p, f_null );
7171 return;
7172 }
7173 const time_duration plantEpoch = seed->get_plant_epoch();
7174 if( seed->age() >= plantEpoch * furn.plant->growth_multiplier &&
7175 !furn.has_flag( "GROWTH_HARVEST" ) ) {
7176 if( seed->age() < plantEpoch * 2 ) {
7177 if( has_flag_furn( "GROWTH_SEEDLING", p ) ) {
7178 return;
7179 }
7180
7181 // Remove fertilizer if any
7182 map_stack::iterator fertilizer = std::find_if( items.begin(), items.end(), []( const item & it ) {
7183 return it.has_flag( "FERTILIZER" );
7184 } );
7185 if( fertilizer != items.end() ) {
7186 items.erase( fertilizer );
7187 }
7188
7189 rotten_item_spawn( *seed, p );
7190 furn_set( p, furn_str_id( furn.plant->transform ) );
7191 } else if( seed->age() < plantEpoch * 3 * furn.plant->growth_multiplier ) {
7192 if( has_flag_furn( "GROWTH_MATURE", p ) ) {
7193 return;
7194 }
7195
7196 // Remove fertilizer if any
7197 map_stack::iterator fertilizer = std::find_if( items.begin(), items.end(), []( const item & it ) {
7198 return it.has_flag( "FERTILIZER" );
7199 } );
7200 if( fertilizer != items.end() ) {
7201 items.erase( fertilizer );
7202 }
7203
7204 rotten_item_spawn( *seed, p );
7205 //You've skipped the seedling stage so roll monsters twice
7206 if( !has_flag_furn( "GROWTH_SEEDLING", p ) ) {
7207 rotten_item_spawn( *seed, p );
7208 }
7209 furn_set( p, furn_str_id( furn.plant->transform ) );
7210 } else {
7211 //You've skipped two stages so roll monsters two times
7212 if( has_flag_furn( "GROWTH_SEEDLING", p ) ) {
7213 rotten_item_spawn( *seed, p );
7214 rotten_item_spawn( *seed, p );
7215 //One stage change
7216 } else if( has_flag_furn( "GROWTH_MATURE", p ) ) {
7217 rotten_item_spawn( *seed, p );
7218 //Goes from seed to harvest in one check
7219 } else {
7220 rotten_item_spawn( *seed, p );
7221 rotten_item_spawn( *seed, p );
7222 rotten_item_spawn( *seed, p );
7223 }
7224 furn_set( p, furn_str_id( furn.plant->transform ) );
7225 }
7226 }
7227}
iterator erase(const_iterator it) override
Definition: map.cpp:152
void rotten_item_spawn(const item &item, const tripoint &p)
Checks to see if the item that is rotting away generates a creature when it does.
Definition: map.cpp:7103
string_id< furn_t > furn_str_id
Definition: type_id.h:65

References item_stack::begin(), dbg, item_stack::end(), map_stack::erase(), Error, f_null, furn(), furn_set(), getabs(), has_flag_furn(), i_at(), i_clear(), int_id< T >::id(), int_id< T >::obj(), overmap_buffer, rotten_item_spawn(), iuse::seed(), string_id< T >::str(), and overmapbuffer::ter().

Referenced by actualize().

◆ has_adjacent_furniture_with()

bool map::has_adjacent_furniture_with ( const tripoint p,
const std::function< bool(const furn_t &)> &  filter 
)

Returns true if there is furniture for which filter returns true in a 1 tile radius of p.

Pass return_true<furn_t> to detect all adjacent furniture.

Parameters
pthe location to check at
filterwhat to filter the furniture by.

Definition at line 2741 of file map.cpp.

2743{
2744 for( const tripoint &adj : points_in_radius( p, 1 ) ) {
2745 if( has_furn( adj ) && filter( furn( adj ).obj() ) ) {
2746 return true;
2747 }
2748 }
2749
2750 return false;
2751}

References furn(), has_furn(), and points_in_radius().

◆ has_flag() [1/4]

bool map::has_flag ( const std::string &  flag,
const point p 
) const
inline

Definition at line 969 of file map.h.

969 {
970 return has_flag( flag, tripoint( p, abs_sub.z ) );
971 }

References abs_sub, has_flag(), and tripoint::z.

◆ has_flag() [2/4]

bool map::has_flag ( const std::string &  flag,
const tripoint p 
) const

Definition at line 2293 of file map.cpp.

2294{
2295 return has_flag_ter_or_furn( flag, p ); // Does bound checking
2296}

References has_flag_ter_or_furn().

Referenced by accessible_items(), Character::activate_bionic(), add_item(), add_item_or_charges(), npc::assess_danger(), bash(), bash_ter_furn(), bash_ter_success(), start_location::burn(), activity_handlers::burrow_finish(), game::butcher(), can_do_activity_there(), can_examine_at(), can_move_vertical_at(), can_put_items_ter_furn(), monster::can_reach_to(), iexamine::chainfence(), construct::check_empty(), vehicle::check_falling_or_floating(), construct::check_support(), chop_tree_activity(), climb_difficulty(), close_door(), doors::close_door(), collapse_at(), collapse_check(), consider_butchery(), iexamine::curtains(), displace_water(), dont_draw_lower_floor(), iexamine::door_peephole(), draw_lab(), drop_everything(), drop_or_embed_projectile(), iexamine::elevator(), explosion_handler::emp_blast(), game::examine(), computer_session::failure_shutdown(), features(), find_closest_stair(), game::find_or_make_stairs(), flammable_items_at(), game::fling_creature(), game::forced_door_closing(), generic_multi_activity_do(), game::get_dangerous_tile(), get_fire_fuel_string(), game::get_fishable_locations(), overmap_ui::get_overmap_path_to(), game::grabbed_furn_move(), has_flag(), has_nearby_chair(), has_nearby_table(), haul(), hit_with_fire(), vehicle::interact_with(), is_divable(), game::is_empty(), is_flammable(), is_water_shallow_current(), game::knockback(), mine_activity(), mop_spills(), monster::move(), avatar_action::move(), npc::move_to(), move_vehicle(), game::moving_vehicle_dismount(), MapExtras::mx_minefield(), item::on_drop(), open(), open_door(), vehicle::part_collision(), activity_handlers::pickaxe_finish(), game::place_player(), game::print_fields_info(), game::print_items_info(), process_fields_in_submap(), propagate_field(), propagate_suspension_check(), avatar_action::ramp_move(), rate_location(), route(), area_expander::run(), Character::run_cost(), conditional_t< T >::set_is_outside(), vehicle::shift_zlevel(), shoot(), spawn_an_item(), spawn_items(), fungal_effects::spread_fungus(), fungal_effects::spread_fungus_one_tile(), monster::stumble(), avatar_action::swim(), game::update_stair_monsters(), editmap::update_view_with_help(), place_trap_actor::use(), deploy_tent_actor::use(), use_charges_from_furn(), game::use_computer(), game::vertical_move(), vertical_move_destination(), game::walk_move(), water_from(), and npc::worker_downtime().

◆ has_flag() [3/4]

bool map::has_flag ( ter_bitflags  flag,
const point p 
) const
inline

Definition at line 1000 of file map.h.

1000 {
1001 return has_flag( flag, tripoint( p, abs_sub.z ) );
1002 }

References abs_sub, has_flag(), and tripoint::z.

◆ has_flag() [4/4]

bool map::has_flag ( ter_bitflags  flag,
const tripoint p 
) const

Definition at line 2336 of file map.cpp.

2337{
2338 return has_flag_ter_or_furn( flag, p ); // Does bound checking
2339}

References has_flag_ter_or_furn().

◆ has_flag_furn() [1/4]

bool map::has_flag_furn ( const std::string &  flag,
const point p 
) const
inline

Definition at line 989 of file map.h.

989 {
990 return has_flag_furn( flag, tripoint( p, abs_sub.z ) );
991 }

References abs_sub, has_flag_furn(), and tripoint::z.

◆ has_flag_furn() [2/4]

◆ has_flag_furn() [3/4]

bool map::has_flag_furn ( ter_bitflags  flag,
const point p 
) const
inline

Definition at line 1010 of file map.h.

1010 {
1011 return has_flag_furn( flag, tripoint( p, abs_sub.z ) );
1012 }

References abs_sub, has_flag_furn(), and tripoint::z.

◆ has_flag_furn() [4/4]

bool map::has_flag_furn ( ter_bitflags  flag,
const tripoint p 
) const

Definition at line 2346 of file map.cpp.

2347{
2348 return furn( p ).obj().has_flag( flag );
2349}

References furn(), map_data_common_t::has_flag(), and int_id< T >::obj().

◆ has_flag_ter() [1/4]

bool map::has_flag_ter ( const std::string &  flag,
const point p 
) const
inline

Definition at line 984 of file map.h.

984 {
985 return has_flag_ter( flag, tripoint( p, abs_sub.z ) );
986 }

References abs_sub, has_flag_ter(), and tripoint::z.

◆ has_flag_ter() [2/4]

◆ has_flag_ter() [3/4]

bool map::has_flag_ter ( ter_bitflags  flag,
const point p 
) const
inline

Definition at line 1005 of file map.h.

1005 {
1006 return has_flag_ter( flag, tripoint( p, abs_sub.z ) );
1007 }

References abs_sub, has_flag_ter(), and tripoint::z.

◆ has_flag_ter() [4/4]

bool map::has_flag_ter ( ter_bitflags  flag,
const tripoint p 
) const

Definition at line 2341 of file map.cpp.

2342{
2343 return ter( p ).obj().has_flag( flag );
2344}

References map_data_common_t::has_flag(), int_id< T >::obj(), and ter().

◆ has_flag_ter_or_furn() [1/4]

bool map::has_flag_ter_or_furn ( const std::string &  flag,
const point p 
) const
inline

Definition at line 994 of file map.h.

994 {
995 return has_flag_ter_or_furn( flag, tripoint( p, abs_sub.z ) );
996 }

References abs_sub, has_flag_ter_or_furn(), and tripoint::z.

◆ has_flag_ter_or_furn() [2/4]

◆ has_flag_ter_or_furn() [3/4]

bool map::has_flag_ter_or_furn ( ter_bitflags  flag,
const point p 
) const
inline

Definition at line 1015 of file map.h.

1015 {
1016 return has_flag_ter_or_furn( flag, tripoint( p, abs_sub.z ) );
1017 }

References abs_sub, has_flag_ter_or_furn(), and tripoint::z.

◆ has_flag_ter_or_furn() [4/4]

bool map::has_flag_ter_or_furn ( ter_bitflags  flag,
const tripoint p 
) const

Definition at line 2351 of file map.cpp.

2352{
2353 if( !inbounds( p ) ) {
2354 return false;
2355 }
2356
2357 point l;
2358 submap *const current_submap = get_submap_at( p, l );
2359
2360 return current_submap && //FIXME: can be null during mapgen
2361 ( current_submap->get_ter( l ).obj().has_flag( flag ) ||
2362 current_submap->get_furn( l ).obj().has_flag( flag ) );
2363}

References submap::get_furn(), get_submap_at(), submap::get_ter(), map_data_common_t::has_flag(), inbounds(), and int_id< T >::obj().

◆ has_floor()

bool map::has_floor ( const tripoint p) const

◆ has_floor_or_support()

bool map::has_floor_or_support ( const tripoint p) const

Definition at line 2039 of file map.cpp.

2040{
2041 const tripoint below( p.xy(), p.z - 1 );
2042 return !valid_move( p, below, false, true );
2043}

References valid_move(), tripoint::xy(), and tripoint::z.

Referenced by monster::move(), game::print_terrain_info(), avatar_action::ramp_move(), reachable_flood_steps(), smash(), and game::vertical_move().

◆ has_furn() [1/2]

bool map::has_furn ( const point p) const
inline

Definition at line 854 of file map.h.

854 {
855 return has_furn( tripoint( p, abs_sub.z ) );
856 }

References abs_sub, has_furn(), and tripoint::z.

◆ has_furn() [2/2]

◆ has_graffiti_at()

bool map::has_graffiti_at ( const tripoint p) const

Definition at line 7833 of file map.cpp.

7834{
7835 if( !inbounds( p ) ) {
7836 return false;
7837 }
7838 point l;
7839 submap *const current_submap = get_submap_at( p, l );
7840 return current_submap->has_graffiti( l );
7841}
bool has_graffiti(const point &p) const
Definition: submap.cpp:83

References get_submap_at(), submap::has_graffiti(), and inbounds().

Referenced by editmap::draw_main_ui_overlay(), advanced_inv_area::init(), game::place_player(), game::print_graffiti_info(), and editmap::update_view_with_help().

◆ has_items()

bool map::has_items ( const tripoint p) const

Checks for existence of items.

Faster than i_at(p).empty

Definition at line 4760 of file map.cpp.

4761{
4762 if( !inbounds( p ) ) {
4763 return false;
4764 }
4765
4766 point l;
4767 submap *const current_submap = get_submap_at( p, l );
4768
4769 return !current_submap->get_items( l ).empty();
4770}

References submap::get_items(), get_submap_at(), and inbounds().

Referenced by Character::activate_bionic(), bash_items(), can_do_activity_there(), can_examine_at(), can_pickup_at(), drop_furniture(), drop_items(), flammable_items_at(), inventory::form_from_map(), generate_lightmap(), has_clear_path_to_pickup_items(), haul(), iuse::note_bionics(), npc::pick_up_item(), game::place_player(), sees_some_items(), and smash_items().

◆ has_nearby_chair()

bool map::has_nearby_chair ( const tripoint p,
int  radius = 1 
)

Check whether a chair or vehicle seat is nearby.

Definition at line 2780 of file map.cpp.

2781{
2782 for( const tripoint &pt : points_in_radius( p, radius ) ) {
2783 const optional_vpart_position vp = veh_at( pt );
2784 if( has_flag( "CAN_SIT", pt ) ) {
2785 return true;
2786 }
2787 if( vp && vp->vehicle().has_part( "SEAT" ) ) {
2788 return true;
2789 }
2790 }
2791 return false;
2792}

References has_flag(), points_in_radius(), and veh_at().

◆ has_nearby_fire()

bool map::has_nearby_fire ( const tripoint p,
int  radius = 1 
)

Definition at line 2753 of file map.cpp.

2754{
2755 for( const tripoint &pt : points_in_radius( p, radius ) ) {
2756 if( get_field( pt, fd_fire ) != nullptr ) {
2757 return true;
2758 }
2759 if( has_flag_ter_or_furn( "USABLE_FIRE", pt ) ) {
2760 return true;
2761 }
2762 }
2763 return false;
2764}

References fd_fire, get_field(), has_flag_ter_or_furn(), and points_in_radius().

Referenced by iexamine::fireplace(), and inventory::form_from_map().

◆ has_nearby_table()

bool map::has_nearby_table ( const tripoint p,
int  radius = 1 
)

Check whether a table/workbench/vehicle kitchen or other flat surface is nearby that could be used for crafting or eating.

Definition at line 2766 of file map.cpp.

2767{
2768 for( const tripoint &pt : points_in_radius( p, radius ) ) {
2769 const optional_vpart_position vp = veh_at( p );
2770 if( has_flag( "FLAT_SURF", pt ) ) {
2771 return true;
2772 }
2773 if( vp && ( vp->vehicle().has_part( "KITCHEN" ) || vp->vehicle().has_part( "FLAT_SURF" ) ) ) {
2774 return true;
2775 }
2776 }
2777 return false;
2778}

References has_flag(), points_in_radius(), and veh_at().

Referenced by can_do_activity_there(), and consider_butchery().

◆ has_zlevels()

◆ hit_with_acid()

bool map::hit_with_acid ( const tripoint p)

Definition at line 3819 of file map.cpp.

3820{
3821 if( passable( p ) ) {
3822 return false; // Didn't hit the tile!
3823 }
3824 const ter_id t = ter( p );
3825 if( t == t_wall_glass || t == t_wall_glass_alarm ||
3826 t == t_vat ) {
3827 ter_set( p, t_floor );
3828 } else if( t == t_door_c || t == t_door_locked || t == t_door_locked_peep ||
3829 t == t_door_locked_alarm ) {
3830 if( one_in( 3 ) ) {
3831 ter_set( p, t_door_b );
3832 }
3833 } else if( t == t_door_bar_c || t == t_door_bar_o || t == t_door_bar_locked || t == t_bars ||
3834 t == t_reb_cage ) {
3835 ter_set( p, t_floor );
3836 add_msg( m_warning, _( "The metal bars melt!" ) );
3837 } else if( t == t_door_b ) {
3838 if( one_in( 4 ) ) {
3839 ter_set( p, t_door_frame );
3840 } else {
3841 return false;
3842 }
3843 } else if( t == t_window || t == t_window_alarm || t == t_window_no_curtains ) {
3844 ter_set( p, t_window_empty );
3845 } else if( t == t_wax ) {
3846 ter_set( p, t_floor_wax );
3847 } else if( t == t_gas_pump || t == t_gas_pump_smashed ) {
3848 return false;
3849 } else if( t == t_card_science || t == t_card_military || t == t_card_industrial ) {
3851 }
3852 return true;
3853}
@ m_warning
Definition: enums.h:264
ter_id t_card_industrial
Definition: mapdata.cpp:722
ter_id t_floor_wax
Definition: mapdata.cpp:685
ter_id t_reb_cage
Definition: mapdata.cpp:654
ter_id t_card_military
Definition: mapdata.cpp:722
ter_id t_door_bar_locked
Definition: mapdata.cpp:663
ter_id t_window_alarm
Definition: mapdata.cpp:668
ter_id t_door_bar_o
Definition: mapdata.cpp:663
ter_id t_gas_pump
Definition: mapdata.cpp:698
ter_id t_wall_glass_alarm
Definition: mapdata.cpp:649
ter_id t_card_reader_broken
Definition: mapdata.cpp:722
ter_id t_gas_pump_smashed
Definition: mapdata.cpp:698
ter_id t_door_locked_peep
Definition: mapdata.cpp:657
ter_id t_door_bar_c
Definition: mapdata.cpp:663
ter_id t_door_frame
Definition: mapdata.cpp:658
ter_id t_vat
Definition: mapdata.cpp:710
ter_id t_window_no_curtains
Definition: mapdata.cpp:672
ter_id t_wax
Definition: mapdata.cpp:685
ter_id t_window_empty
Definition: mapdata.cpp:668
ter_id t_door_b
Definition: mapdata.cpp:656

References _, add_msg(), m_warning, one_in(), passable(), t_bars, t_card_industrial, t_card_military, t_card_reader_broken, t_card_science, t_door_b, t_door_bar_c, t_door_bar_locked, t_door_bar_o, t_door_c, t_door_frame, t_door_locked, t_door_locked_alarm, t_door_locked_peep, t_floor, t_floor_wax, t_gas_pump, t_gas_pump_smashed, t_reb_cage, t_vat, t_wall_glass, t_wall_glass_alarm, t_wax, t_window, t_window_alarm, t_window_empty, t_window_no_curtains, ter(), and ter_set().

◆ hit_with_fire()

bool map::hit_with_fire ( const tripoint p)

Definition at line 3856 of file map.cpp.

3857{
3858 if( passable( p ) ) {
3859 return false; // Didn't hit the tile!
3860 }
3861
3862 // non passable but flammable terrain, set it on fire
3863 if( has_flag( "FLAMMABLE", p ) || has_flag( "FLAMMABLE_ASH", p ) ) {
3864 add_field( p, fd_fire, 3 );
3865 }
3866 return true;
3867}

References add_field(), fd_fire, has_flag(), and passable().

Referenced by mattack::flame().

◆ hoist_submap_camp()

basecamp map::hoist_submap_camp ( const tripoint p)

Definition at line 5573 of file map.cpp.

5574{
5575 basecamp *pcamp = get_submap_at( p )->camp.get();
5576 return pcamp ? *pcamp : basecamp();
5577}
std::unique_ptr< basecamp > camp
Definition: submap.h:249

References submap::camp, and get_submap_at().

Referenced by game::validate_camps().

◆ i_at() [1/2]

map_stack map::i_at ( const point p)
inline

Definition at line 1241 of file map.h.

1241 {
1242 return i_at( tripoint( p, abs_sub.z ) );
1243 }

References abs_sub, i_at(), and tripoint::z.

◆ i_at() [2/2]

map_stack map::i_at ( const tripoint p)

Definition at line 4079 of file map.cpp.

4080{
4081 if( !inbounds( p ) ) {
4082 nulitems.clear();
4083 return map_stack{ &nulitems, p, this };
4084 }
4085
4086 point l;
4087 submap *const current_submap = get_submap_at( p, l );
4088
4089 return map_stack{ &current_submap->get_items( l ), p, this };
4090}
static cata::colony< item > nulitems
Definition: map.cpp:140

References submap::get_items(), get_submap_at(), inbounds(), and nulitems.

Referenced by computer_session::action_blood_anal(), computer_session::action_conveyor(), computer_session::action_data_anal(), computer_session::action_irradiator(), computer_session::action_list_bionics(), computer_session::action_sample(), Character::activate_bionic(), activity_on_turn_move_loot(), add_item_or_charges(), advanced_inventory_pane::add_items_from_area(), iexamine::aggie_plant(), apply_camp_ownership(), apply_faction_ownership(), iexamine::arcfurnace_empty(), iexamine::arcfurnace_full(), are_requirements_nearby(), iexamine::autoclave_full(), Character::base_comfort_value(), bash_furn_success(), bash_items(), board_up(), MapExtras::burned_ground_parser(), game::butcher(), butcher_corpse_activity(), can_butcher_at(), can_do_activity_there(), iexamine::can_fertilize(), advanced_inventory::change_square(), construct::check_empty(), chop_plank_activity(), doors::close_door(), complete_construction(), iuse::directional_antenna(), iexamine::dirtmound(), displace_items_except_one_liquid(), basecamp::distribute_food(), construct::done_grave(), drop_furniture(), drop_items(), editmap::edit_itm(), iexamine::elevator(), explosion_handler::emp_blast(), game::examine(), computer_session::failure_destroy_blood(), computer_session::failure_destroy_data(), farm_action(), iexamine::fertilize_plant(), fetch_activity(), talk_function::field_harvest(), fill_funnels(), activity_handlers::fill_liquid_do_turn(), find_auto_consume(), npc::find_corpse_to_pulp(), npc::find_item(), game::find_nearby_items(), flammable_items_at(), Character::floor_item_warmth(), game::forced_door_closing(), basecamp::form_crafting_inventory(), inventory::form_from_map(), free_volume(), fromPumpFuel(), furnname(), iexamine::fvat_empty(), iexamine::fvat_full(), iexamine::gaspump(), generate_lightmap(), generic_multi_activity_locations(), advanced_inv_area::get_container(), player::get_eligible_containers_for_crafting(), advanced_inv_area::get_item_count(), iexamine::getNearFilledGasTank(), game::grabbed_furn_move(), grow_plant(), liquid_handler::handle_liquid_from_ground(), iexamine::harvest_plant(), i_at(), i_rem(), Character::is_snuggling(), activity_handlers::jackhammer_finish(), iexamine::keg(), iexamine::kiln_empty(), iexamine::kiln_full(), advanced_inventory_pane::load_settings(), activity_handlers::longsalvage_finish(), talk_function::loot_building(), max_volume(), mill_activate(), iexamine::mill_finalize(), mop_spills(), advanced_inventory::move_all_items(), MapExtras::mx_supplydrop(), iuse::note_bionics(), om_harvest_itm(), iexamine::pedestal_temple(), iexamine::pedestal_wyrm(), tutorial_game::per_turn(), npc::pick_up_item_map(), activity_handlers::pickaxe_finish(), game::place_player(), iexamine::pour_into_keg(), firestarter_actor::prep_firestarter_use(), game::print_items_info(), process_fields_in_submap(), process_items_in_submap(), produce_sap(), activity_handlers::pulp_do_turn(), iexamine::quern_examine(), plot_options::query_seed(), iexamine::recycle_compactor(), iexamine::reload_furniture(), requirements_map(), rod_fish(), npc::see_item_say_smth(), serialize_liquid_source(), iexamine::shrub_wildveggies(), smash(), smash_items(), smoker_activate(), smoker_finalize(), iexamine::smoker_options(), fungal_effects::spread_fungus_one_tile(), game::start_hauling(), basecamp::start_relay_hide_site(), stored_volume(), tidy_activity(), tinder_at(), iexamine::toilet(), iexamine::toPumpFuel(), iexamine::tree_maple_tapped(), try_fuel_fire(), editmap::update_view_with_help(), use_amount_square(), use_charges(), use_charges_from_furn(), iexamine::use_furn_fake_item(), and iexamine::vending().

◆ i_clear() [1/2]

void map::i_clear ( const point p)
inline

Definition at line 1246 of file map.h.

1246 {
1247 i_clear( tripoint( p, abs_sub.z ) );
1248 }

References abs_sub, i_clear(), and tripoint::z.

◆ i_clear() [2/2]

void map::i_clear ( const tripoint p)

Definition at line 4117 of file map.cpp.

4118{
4119 point l;
4120 submap *const current_submap = get_submap_at( p, l );
4121
4122 for( item &it : current_submap->get_items( l ) ) {
4123 // remove from the active items cache (if it isn't there does nothing)
4124 current_submap->active_items.remove( &it );
4125 }
4126 if( current_submap->active_items.empty() ) {
4127 submaps_with_active_items.erase( tripoint( abs_sub.x + p.x / SEEX, abs_sub.y + p.y / SEEY, p.z ) );
4128 }
4129
4130 current_submap->set_lum( l, 0 );
4131 current_submap->get_items( l ).clear();
4132}
void remove(const item *it)
Removes the item if it is in the cache.
void set_lum(const point &p, uint8_t luminance)
Definition: submap.h:125

References abs_sub, submap::active_items, active_item_cache::empty(), submap::get_items(), get_submap_at(), active_item_cache::remove(), SEEX, SEEY, submap::set_lum(), submaps_with_active_items, tripoint::x, tripoint::y, and tripoint::z.

Referenced by computer_session::action_conveyor(), iexamine::aggie_plant(), jmapgen_terrain::apply(), iexamine::arcfurnace_empty(), board_up(), doors::close_door(), MapExtras::dead_vegetation_parser(), basecamp::distribute_food(), draw_lab(), drop_furniture(), drop_items(), computer_session::failure_destroy_blood(), computer_session::failure_destroy_data(), farm_action(), iexamine::fertilize_plant(), talk_function::field_harvest(), iexamine::fvat_empty(), iexamine::fvat_full(), game::grabbed_furn_move(), grow_plant(), iexamine::harvest_plant(), i_clear(), iexamine::keg(), iexamine::kiln_empty(), mapgen_lake_shore(), om_harvest_itm(), iexamine::pedestal_temple(), iexamine::pedestal_wyrm(), rad_scorch(), and iexamine::tree_maple_tapped().

◆ i_rem() [1/4]

map_stack::iterator map::i_rem ( const point location,
map_stack::const_iterator  it 
)
inline

Definition at line 1252 of file map.h.

1252 {
1253 return i_rem( tripoint( location, abs_sub.z ), it );
1254 }
map_stack::iterator i_rem(const tripoint &p, map_stack::const_iterator it)
Definition: map.cpp:4092

References abs_sub, i_rem(), and tripoint::z.

◆ i_rem() [2/4]

void map::i_rem ( const point p,
item it 
)
inline

Definition at line 1256 of file map.h.

1256 {
1257 i_rem( tripoint( p, abs_sub.z ), it );
1258 }

References abs_sub, i_rem(), and tripoint::z.

◆ i_rem() [3/4]

void map::i_rem ( const tripoint p,
item it 
)

Definition at line 4108 of file map.cpp.

4109{
4110 map_stack map_items = i_at( p );
4112 if( iter != map_items.end() ) {
4113 i_rem( p, iter );
4114 }
4115}
iterator get_iterator_from_pointer(item *it)
Definition: item_stack.cpp:68

References item_stack::end(), item_stack::get_iterator_from_pointer(), i_at(), and i_rem().

◆ i_rem() [4/4]

map_stack::iterator map::i_rem ( const tripoint p,
map_stack::const_iterator  it 
)

Definition at line 4092 of file map.cpp.

4093{
4094 point l;
4095 submap *const current_submap = get_submap_at( p, l );
4096
4097 // remove from the active items cache (if it isn't there does nothing)
4098 current_submap->active_items.remove( &*it );
4099 if( current_submap->active_items.empty() ) {
4100 submaps_with_active_items.erase( tripoint( abs_sub.x + p.x / SEEX, abs_sub.y + p.y / SEEY, p.z ) );
4101 }
4102
4103 current_submap->update_lum_rem( l, *it );
4104
4105 return current_submap->get_items( l ).erase( it );
4106}
void update_lum_rem(const point &p, const item &i)
Definition: submap.h:137

References abs_sub, submap::active_items, active_item_cache::empty(), submap::get_items(), get_submap_at(), active_item_cache::remove(), SEEX, SEEY, submaps_with_active_items, submap::update_lum_rem(), tripoint::x, tripoint::y, and tripoint::z.

Referenced by computer_session::action_irradiator(), chop_plank_activity(), iexamine::elevator(), map_stack::erase(), iexamine::fvat_full(), i_rem(), mill_activate(), move_item(), om_set_hide_site(), rcdrive(), remove_rotten_items(), game::save_cyborg(), smash_items(), and smoker_activate().

◆ impassable() [1/2]

bool map::impassable ( const point p) const
inline

Definition at line 632 of file map.h.

632 {
633 return !passable( p );
634 }

References passable().

◆ impassable() [2/2]

◆ impassable_ter_furn()

bool map::impassable_ter_furn ( const tripoint p) const

Definition at line 1828 of file map.cpp.

1829{
1830 return !passable_ter_furn( p );
1831}
bool passable_ter_furn(const tripoint &p) const
Definition: map.cpp:1833

References passable_ter_furn().

Referenced by vehicle::check_heli_ascend(), vehicle::check_heli_descend(), climb_difficulty(), displace_water(), and vehicle::part_collision().

◆ inbounds() [1/2]

bool map::inbounds ( const point p) const
inline

Definition at line 1669 of file map.h.

1669 {
1670 return inbounds( tripoint( p, 0 ) );
1671 }

References inbounds().

◆ inbounds() [2/2]

bool map::inbounds ( const tripoint p) const
virtual

Reimplemented in tinymap.

Definition at line 7756 of file map.cpp.

7757{
7758 static constexpr tripoint map_boundary_min( 0, 0, -OVERMAP_DEPTH );
7759 static constexpr tripoint map_boundary_max( MAPSIZE_Y, MAPSIZE_X, OVERMAP_HEIGHT + 1 );
7760
7761 static constexpr half_open_cuboid<tripoint> map_boundaries(
7762 map_boundary_min, map_boundary_max );
7763
7764 return map_boundaries.contains( p );
7765}

References half_open_cuboid< Tripoint, >::contains(), MAPSIZE_X, MAPSIZE_Y, OVERMAP_DEPTH, and OVERMAP_HEIGHT.

Referenced by vehicle::act_on_map(), activity_on_turn_move_loot(), add_field(), add_item(), MapgenRemovePartHandler::add_item_or_charges(), add_item_or_charges(), add_vehicle(), add_vehicle_to_cache(), adjust_radiation(), ambient_light_at(), apply_light_source(), bash(), bash_rating(), build_sunlight_cache(), Character::check_outbounds_activity(), clear_path(), clear_vehicle_cache(), clear_vehicle_point_from_cache(), computer_at(), delete_graffiti(), delete_signage(), displace_vehicle(), explosion_handler::do_blast(), do_vehicle_caching(), draw(), game::draw_look_around_cursor(), drawsq(), ranged::execute_shaped_attack(), field_at(), furn(), furn_set(), generate_lightmap(), generic_multi_activity_handler(), get_field(), get_known_connections(), get_radiation(), get_signage(), get_submap_at(), get_temperature(), graffiti_at(), has_flag_ter_or_furn(), has_floor(), has_graffiti_at(), has_items(), i_at(), inbounds(), is_bashable(), is_outside(), light_at(), game::load_npcs(), maptile_at(), map_stack::max_volume(), move_cost(), move_cost_ter_furn(), obscured_by_vehicle_rotation(), obstructed_by_vehicle_rotation(), activity_handlers::operation_do_turn(), partial_con_at(), partial_con_remove(), partial_con_set(), pl_line_of_sight(), pl_sees(), game::print_all_tile_info(), remove_field(), remove_trap(), route(), npc::saw_player_recently(), sees(), set_graffiti(), set_radiation(), set_seen_cache_dirty(), set_signage(), set_temperature(), set_transparency_cache_dirty(), game::shift_monsters(), shift_traps(), shoot(), spawn_items(), ter(), ter_set(), tr_at(), trap_set(), update_suspension_cache(), valid_move(), and veh_at().

◆ inbounds_z()

◆ invalidate_map_cache()

◆ invalidate_max_populated_zlev()

void map::invalidate_max_populated_zlev ( int  zlev)
private

Conditionally invalidates max_pupulated_zlev cache if the submap uniformity change occurs above current max_pupulated_zlev value.

Parameters
zlevzlevel where uniformity change occured

Definition at line 8954 of file map.cpp.

8955{
8956 if( max_populated_zlev && max_populated_zlev->second < zlev ) {
8957 max_populated_zlev->second = zlev;
8958 }
8959}

References max_populated_zlev.

Referenced by add_field(), add_item(), add_vehicle(), displace_vehicle(), furn_set(), shift_vehicle_z(), and ter_set().

◆ is_bashable() [1/2]

bool map::is_bashable ( const point p) const
inline

Definition at line 1022 of file map.h.

1022 {
1023 return is_bashable( tripoint( p, abs_sub.z ) );
1024 }

References abs_sub, is_bashable(), and tripoint::z.

◆ is_bashable() [2/2]

bool map::is_bashable ( const tripoint p,
bool  allow_floor = false 
) const

Returns true if there is a bashable vehicle part or the furn/terrain is bashable at p.

Definition at line 2414 of file map.cpp.

2415{
2416 if( !inbounds( p ) ) {
2417 dbg( DL::Warn ) << "Looking for out-of-bounds is_bashable at " << p;
2418 return false;
2419 }
2420
2421 if( veh_at( p ).obstacle_at_part() ) {
2422 return true;
2423 }
2424
2425 if( has_furn( p ) && furn( p ).obj().bash.str_max != -1 ) {
2426 return true;
2427 }
2428
2429 const auto &ter_bash = ter( p ).obj().bash;
2430 return ter_bash.str_max != -1 && ( !ter_bash.bash_below || allow_floor );
2431}

References bash(), map_data_common_t::bash, dbg, furn(), has_furn(), inbounds(), int_id< T >::obj(), map_bash_info::str_max, ter(), veh_at(), and Warn.

Referenced by MapExtras::burned_ground_parser(), activity_handlers::burrow_finish(), features(), game::fling_creature(), is_bashable(), npc::move_to(), MapExtras::mx_helicopter(), and activity_handlers::pickaxe_finish().

◆ is_bashable_furn() [1/2]

bool map::is_bashable_furn ( const point p) const
inline

Definition at line 1032 of file map.h.

1032 {
1033 return is_bashable_furn( tripoint( p, abs_sub.z ) );
1034 }
bool is_bashable_furn(const tripoint &p) const
Returns true if the furniture at p is bashable.
Definition: map.cpp:2439

References abs_sub, is_bashable_furn(), and tripoint::z.

◆ is_bashable_furn() [2/2]

bool map::is_bashable_furn ( const tripoint p) const

Returns true if the furniture at p is bashable.

Definition at line 2439 of file map.cpp.

2440{
2441 return has_furn( p ) && furn( p ).obj().bash.str_max != -1;
2442}

References map_data_common_t::bash, furn(), has_furn(), int_id< T >::obj(), and map_bash_info::str_max.

Referenced by is_bashable_furn(), is_bashable_ter_furn(), and make_rubble().

◆ is_bashable_ter() [1/2]

bool map::is_bashable_ter ( const point p) const
inline

Definition at line 1027 of file map.h.

1027 {
1028 return is_bashable_ter( tripoint( p, abs_sub.z ) );
1029 }
bool is_bashable_ter(const tripoint &p, bool allow_floor=false) const
Returns true if the terrain at p is bashable.
Definition: map.cpp:2433

References abs_sub, is_bashable_ter(), and tripoint::z.

◆ is_bashable_ter() [2/2]

bool map::is_bashable_ter ( const tripoint p,
bool  allow_floor = false 
) const

Returns true if the terrain at p is bashable.

Definition at line 2433 of file map.cpp.

2434{
2435 const auto &ter_bash = ter( p ).obj().bash;
2436 return ter_bash.str_max != -1 && ( !ter_bash.bash_below || allow_floor );
2437}

References map_data_common_t::bash, int_id< T >::obj(), map_bash_info::str_max, and ter().

Referenced by is_bashable_ter(), is_bashable_ter_furn(), and make_rubble().

◆ is_bashable_ter_furn() [1/2]

bool map::is_bashable_ter_furn ( const point p) const
inline

Definition at line 1037 of file map.h.

1037 {
1038 return is_bashable_ter_furn( tripoint( p, abs_sub.z ) );
1039 }
bool is_bashable_ter_furn(const tripoint &p, bool allow_floor=false) const
Returns true if the furniture or terrain at p is bashable.
Definition: map.cpp:2444

References abs_sub, is_bashable_ter_furn(), and tripoint::z.

◆ is_bashable_ter_furn() [2/2]

bool map::is_bashable_ter_furn ( const tripoint p,
bool  allow_floor = false 
) const

Returns true if the furniture or terrain at p is bashable.

Definition at line 2444 of file map.cpp.

2445{
2446 return is_bashable_furn( p ) || is_bashable_ter( p, allow_floor );
2447}

References is_bashable_furn(), and is_bashable_ter().

Referenced by is_bashable_ter_furn(), and vehicle::part_collision().

◆ is_cornerfloor()

bool map::is_cornerfloor ( const tripoint p) const

Definition at line 8891 of file map.cpp.

8892{
8893 if( impassable( p ) ) {
8894 return false;
8895 }
8896 std::set<tripoint> impassable_adjacent;
8897 for( const tripoint &pt : points_in_radius( p, 1 ) ) {
8898 if( impassable( pt ) ) {
8899 impassable_adjacent.insert( pt );
8900 }
8901 }
8902 if( !impassable_adjacent.empty() ) {
8903 //to check if a floor is a corner we first search if any of its diagonal adjacent points is impassable
8904 std::set< tripoint> diagonals = { p + tripoint_north_east, p + tripoint_north_west, p + tripoint_south_east, p + tripoint_south_west };
8905 for( const tripoint &impassable_diagonal : diagonals ) {
8906 if( impassable_adjacent.count( impassable_diagonal ) != 0 ) {
8907 //for every impassable diagonal found, we check if that diagonal terrain has at least two impassable neighbors that also neighbor point p
8908 int f = 0;
8909 for( const tripoint &l : points_in_radius( impassable_diagonal, 1 ) ) {
8910 if( impassable_adjacent.count( l ) != 0 ) {
8911 f++;
8912 }
8913 if( f > 2 ) {
8914 return true;
8915 }
8916 }
8917 }
8918 }
8919 }
8920 return false;
8921}
static constexpr tripoint tripoint_north_east
Definition: point.h:286
static constexpr tripoint tripoint_north_west
Definition: point.h:292
static constexpr tripoint tripoint_south_east
Definition: point.h:288
static constexpr tripoint tripoint_south_west
Definition: point.h:290

References impassable(), points_in_radius(), tripoint_north_east, tripoint_north_west, tripoint_south_east, and tripoint_south_west.

◆ is_divable() [1/2]

bool map::is_divable ( const point p) const
inline

Definition at line 1080 of file map.h.

1080 {
1081 return is_divable( tripoint( p, abs_sub.z ) );
1082 }
bool is_divable(const tripoint &p) const
Returns whether or not the terrain at the given location can be dived into (by monsters that can swim...
Definition: map.cpp:2558

References abs_sub, is_divable(), and tripoint::z.

◆ is_divable() [2/2]

bool map::is_divable ( const tripoint p) const

Returns whether or not the terrain at the given location can be dived into (by monsters that can swim or are aquatic or non-breathing).

Parameters
pThe coordinate to look at.
Returns
true if the terrain can be dived into; false if not.

Definition at line 2558 of file map.cpp.

2559{
2560 return has_flag( "SWIMMABLE", p ) && has_flag( TFLAG_DEEP_WATER, p );
2561}

References has_flag(), and TFLAG_DEEP_WATER.

Referenced by enchantment::is_active(), is_divable(), and Creature::sees().

◆ is_flammable()

bool map::is_flammable ( const tripoint p)

Returns true if there is a flammable item or field or the furn/terrain is flammable at p.

Definition at line 2642 of file map.cpp.

2643{
2644 if( flammable_items_at( p ) ) {
2645 return true;
2646 }
2647
2648 if( has_flag( "FLAMMABLE", p ) ) {
2649 return true;
2650 }
2651
2652 if( has_flag( "FLAMMABLE_ASH", p ) ) {
2653 return true;
2654 }
2655
2656 if( get_field_intensity( p, fd_web ) > 0 ) {
2657 return true;
2658 }
2659
2660 return false;
2661}
int get_field_intensity(const tripoint &p, const field_type_id &type) const
Get the intensity of a field entry (field_entry::intensity), if there is no field of that type,...
Definition: map.cpp:5367
bool flammable_items_at(const tripoint &p, int threshold=0)
Checks if there are any flammable items on the tile.
Definition: map.cpp:2625

References fd_web, flammable_items_at(), get_field_intensity(), and has_flag().

Referenced by Character::activate_bionic(), and activity_handlers::start_fire_do_turn().

◆ is_harvestable()

bool map::is_harvestable ( const tripoint pos) const

Returns true if point at pos is harvestable right now, with no extra tools.

Definition at line 1630 of file map.cpp.

1631{
1632 const auto &harvest_here = get_harvest( pos );
1633 return !harvest_here.is_null() && !harvest_here->empty();
1634}
const harvest_id & get_harvest(const tripoint &p) const
Returns the full harvest list, for spawning.
Definition: map.cpp:1564

References get_harvest(), and wrapped_vehicle::pos.

Referenced by npc::pick_up_item().

◆ is_last_ter_wall()

bool map::is_last_ter_wall ( bool  no_furn,
const point p,
const point max,
direction  dir 
) const

Check if the last terrain is wall in direction NORTH, SOUTH, WEST or EAST.

Parameters
no_furnif true, the function will stop and return false if it encounters a furniture
pstarting coordinates of check
maxending coordinates of check
dirDirection of check
Returns
true if from x to xmax or y to ymax depending on direction all terrain is floor and the last terrain is a wall

Definition at line 2573 of file map.cpp.

2575{
2576 point mov;
2577 switch( dir ) {
2578 case direction::NORTH:
2579 mov.y = -1;
2580 break;
2581 case direction::SOUTH:
2582 mov.y = 1;
2583 break;
2584 case direction::WEST:
2585 mov.x = -1;
2586 break;
2587 case direction::EAST:
2588 mov.x = 1;
2589 break;
2590 default:
2591 break;
2592 }
2593 point p2( p );
2594 bool result = true;
2595 bool loop = true;
2596 while( ( loop ) && ( ( dir == direction::NORTH && p2.y >= 0 ) ||
2597 ( dir == direction::SOUTH && p2.y < max.y ) ||
2598 ( dir == direction::WEST && p2.x >= 0 ) ||
2599 ( dir == direction::EAST && p2.x < max.x ) ) ) {
2600 if( no_furn && has_furn( p2 ) ) {
2601 loop = false;
2602 result = false;
2603 } else if( !has_flag_ter( "FLAT", p2 ) ) {
2604 loop = false;
2605 if( !has_flag_ter( "WALL", p2 ) ) {
2606 result = false;
2607 }
2608 }
2609 p2.x += mov.x;
2610 p2.y += mov.y;
2611 }
2612 return result;
2613}

References EAST, has_flag_ter(), has_furn(), NORTH, SOUTH, WEST, point::x, and point::y.

Referenced by find_potential_computer_point().

◆ is_outside() [1/2]

bool map::is_outside ( const point p) const
inline

Definition at line 1070 of file map.h.

1070 {
1071 return is_outside( tripoint( p, abs_sub.z ) );
1072 }
bool is_outside(const tripoint &p) const
Definition: map.cpp:2563

References abs_sub, is_outside(), and tripoint::z.

◆ is_outside() [2/2]

◆ is_suspension_valid()

bool map::is_suspension_valid ( const tripoint point)

Checks the four orientations in which a suspended tile could be valid, and returns if the tile is valid.

Definition at line 2962 of file map.cpp.

2963{
2964 if( ter( point + tripoint_east ) != t_open_air
2965 && ter( point + tripoint_west ) != t_open_air ) {
2966 return true;
2967 }
2970 return true;
2971 }
2973 && ter( point + tripoint_north ) != t_open_air ) {
2974 return true;
2975 }
2978 return true;
2979 }
2980 return false;
2981}
static constexpr tripoint tripoint_north
Definition: point.h:285
static constexpr tripoint tripoint_west
Definition: point.h:291
static constexpr tripoint tripoint_east
Definition: point.h:287
static constexpr tripoint tripoint_south
Definition: point.h:289

References t_open_air, ter(), tripoint_east, tripoint_north, tripoint_north_east, tripoint_north_west, tripoint_south, tripoint_south_east, tripoint_south_west, and tripoint_west.

Referenced by collapse_invalid_suspension(), and update_suspension_cache().

◆ is_transparent()

bool map::is_transparent ( const tripoint p) const

Returns whether the tile at p is transparent(you can look past it).

Definition at line 626 of file lightmap.cpp.

627{
629}

References light_transparency(), and LIGHT_TRANSPARENCY_SOLID.

Referenced by ranged::execute_shaped_attack(), ranged::expected_coverage(), get_known_connections(), mattack::riotbot(), and shoot().

◆ is_wall_adjacent()

bool map::is_wall_adjacent ( const tripoint center) const

Definition at line 1768 of file map.cpp.

1769{
1770 for( const tripoint &p : points_in_radius( center, 1 ) ) {
1771 if( p != center && impassable( p ) ) {
1772 return true;
1773 }
1774 }
1775 return false;
1776}

References center, impassable(), and points_in_radius().

Referenced by ma_requirements::is_valid_character().

◆ is_water_shallow_current() [1/2]

bool map::is_water_shallow_current ( const point p) const
inline

Definition at line 1084 of file map.h.

1084 {
1086 }
bool is_water_shallow_current(const tripoint &p) const
Definition: map.cpp:2553

References abs_sub, is_water_shallow_current(), and tripoint::z.

◆ is_water_shallow_current() [2/2]

bool map::is_water_shallow_current ( const tripoint p) const

Definition at line 2553 of file map.cpp.

2554{
2555 return has_flag( "CURRENT", p ) && !has_flag( TFLAG_DEEP_WATER, p );
2556}

References has_flag(), and TFLAG_DEEP_WATER.

Referenced by is_water_shallow_current(), and iexamine::quern_examine().

◆ light_at()

lit_level map::light_at ( const tripoint p) const

Definition at line 592 of file lightmap.cpp.

593{
594 if( !inbounds( p ) ) {
595 return lit_level::DARK; // Out of bounds
596 }
597
598 const auto &map_cache = get_cache_ref( p.z );
599 const auto &lm = map_cache.lm;
600 const auto &sm = map_cache.sm;
601 if( sm[p.x][p.y] >= LIGHT_SOURCE_BRIGHT ) {
602 return lit_level::BRIGHT;
603 }
604
605 const float max_light = lm[p.x][p.y].max();
606 if( max_light >= LIGHT_AMBIENT_LIT ) {
607 return lit_level::LIT;
608 }
609
610 if( max_light >= LIGHT_AMBIENT_LOW ) {
611 return lit_level::LOW;
612 }
613
614 return lit_level::DARK;
615}

References BRIGHT, DARK, get_cache_ref(), inbounds(), LIGHT_AMBIENT_LIT, LIGHT_AMBIENT_LOW, LIGHT_SOURCE_BRIGHT, LIT, LOW, coords::sm, tripoint::x, tripoint::y, and tripoint::z.

Referenced by Creature::sees().

◆ light_transparency()

float map::light_transparency ( const tripoint p) const

Definition at line 631 of file lightmap.cpp.

632{
633 return get_cache_ref( p.z ).transparency_cache[p.x][p.y];
634}

References get_cache_ref(), level_cache::transparency_cache, tripoint::x, tripoint::y, and tripoint::z.

Referenced by generate_lightmap(), and is_transparent().

◆ load() [1/2]

void map::load ( const tripoint w,
bool  update_vehicles,
bool  pump_events = false 
)

Load submaps into grid.

This might create new submaps if the mapbuffer can not deliver the requested submap (as it does not exist on disc). This must be called before the map can be used at all!

Parameters
wglobal coordinates of the submap at grid[0]. This is in submap coordinates.
update_vehiclesIf true, add vehicles to the vehicle cache.
pump_eventsIf true, handle window events during loading. If you set this to true, do ensure that the map is not accessed before this function returns (for example, UIs that draw the map should be disabled).

Definition at line 6609 of file map.cpp.

6610{
6611 for( auto &traps : traplocs ) {
6612 traps.clear();
6613 }
6614 field_furn_locs.clear();
6616 set_abs_sub( w );
6617 for( int gridx = 0; gridx < my_MAPSIZE; gridx++ ) {
6618 for( int gridy = 0; gridy < my_MAPSIZE; gridy++ ) {
6619 loadn( point( gridx, gridy ), update_vehicle );
6620 if( pump_events ) {
6622 }
6623 }
6624 }
6626}
void pump_events()
Resize & refresh if necessary, process all pending window events, and ignore keypresses.
void loadn(const tripoint &grid, bool update_vehicles)
Definition: map.cpp:6991
input_manager inp_mngr
Definition: input.cpp:109

References field_furn_locs, inp_mngr, loadn(), my_MAPSIZE, input_manager::pump_events(), reset_vehicle_cache(), set_abs_sub(), submaps_with_active_items, and traplocs.

Referenced by start_location::add_map_extra(), add_monsters(), start_location::burn(), talk_function::buy_100_logs(), talk_function::buy_10_logs(), create_lab_consoles(), debug_menu::debug(), construct::done_digormine_stair(), construct::done_mine_upstair(), farm_action(), talk_function::field_build_1(), talk_function::field_build_2(), talk_function::field_harvest(), talk_function::field_plant(), find_valid_teleporters_omt(), basecamp::form_crafting_inventory(), mission_start::kill_horde_master(), load(), game::load_map(), talk_function::loot_building(), editmap::mapgen_veh_destroy(), editmap::mapgen_veh_query(), MapExtras::mx_minefield(), om_cutdown_trees(), om_harvest_furn(), om_harvest_itm(), om_harvest_ter(), om_set_hide_site(), teleporter_list::place_avatar_overmap(), Character::place_corpse(), mission_start::place_deposit_box(), mission_start::place_dog(), mission_start::place_npc_software(), mission_start::place_priest_diary(), basecamp::place_results(), game::place_vehicle_nearby(), mission_start::place_zombie_mom(), start_location::prepare_map(), mission_start::ranch_nurse_1(), mission_start::ranch_nurse_2(), mission_start::ranch_nurse_3(), mission_start::ranch_nurse_4(), mission_start::ranch_nurse_5(), mission_start::ranch_nurse_6(), mission_start::ranch_nurse_7(), mission_start::ranch_nurse_8(), mission_start::ranch_nurse_9(), mission_start::ranch_scavenger_1(), mission_start::ranch_scavenger_2(), mission_start::ranch_scavenger_3(), mission_start::reveal_lab_train_depot(), debug_menu::spawn_nested_mapgen(), basecamp::start_relay_hide_site(), update_mapgen_function_json::update_map(), game::vertical_move(), and game::vertical_shift().

◆ load() [2/2]

void map::load ( const tripoint_abs_sm w,
bool  update_vehicles,
bool  pump_events = false 
)

Definition at line 6628 of file map.cpp.

6629{
6630 // TODO: fix point types
6631 load( w.raw(), update_vehicle, pump_events );
6632}
constexpr Point & raw()
Definition: coordinates.h:111
void load(const tripoint &w, bool update_vehicles, bool pump_events=false)
Load submaps into grid.
Definition: map.cpp:6609

References load(), and coords::coord_point< Point, Origin, Scale >::raw().

◆ loadn() [1/2]

void map::loadn ( const point grid,
bool  update_vehicles 
)
inlineprotected

Definition at line 1723 of file map.h.

1723 {
1724 if( zlevels ) {
1725 for( int gridz = -OVERMAP_DEPTH; gridz <= OVERMAP_HEIGHT; gridz++ ) {
1726 loadn( tripoint( grid, gridz ), update_vehicles );
1727 }
1728
1729 // Note: we want it in a separate loop! It is a post-load cleanup
1730 // Since we're adding roofs, we want it to go up (from lowest to highest)
1731 for( int gridz = -OVERMAP_DEPTH; gridz <= OVERMAP_HEIGHT; gridz++ ) {
1732 add_roofs( tripoint( grid, gridz ) );
1733 }
1734 } else {
1735 loadn( tripoint( grid, abs_sub.z ), update_vehicles );
1736 }
1737 }
void add_roofs(const tripoint &grid)
Hacks in missing roofs.
Definition: map.cpp:7460

References abs_sub, add_roofs(), grid, loadn(), OVERMAP_DEPTH, OVERMAP_HEIGHT, tripoint::z, and zlevels.

◆ loadn() [2/2]

void map::loadn ( const tripoint grid,
bool  update_vehicles 
)
protected

Definition at line 6991 of file map.cpp.

6992{
6993 // Cache empty overmap types
6994 static const oter_id rock( "empty_rock" );
6995 static const oter_id air( "open_air" );
6996
6997 const tripoint grid_abs_sub = abs_sub.xy() + grid;
6998 const size_t gridn = get_nonant( grid );
6999
7000 const int old_abs_z = abs_sub.z; // Ugly, but necessary at the moment
7001 abs_sub.z = grid.z;
7002
7003 submap *tmpsub = MAPBUFFER.lookup_submap( grid_abs_sub );
7004 if( tmpsub == nullptr ) {
7005 // It doesn't exist; we must generate it!
7006 dbg( DL::Info ) << "map::loadn: Missing mapbuffer data. Regenerating.";
7007
7008 // Each overmap square is two nonants; to prevent overlap, generate only at
7009 // squares divisible by 2.
7010 // TODO: fix point types
7011 const tripoint_abs_omt grid_abs_omt( sm_to_omt_copy( grid_abs_sub ) );
7012 const tripoint grid_abs_sub_rounded = omt_to_sm_copy( grid_abs_omt.raw() );
7013
7014 const oter_id terrain_type = overmap_buffer.ter( grid_abs_omt );
7015
7016 // Short-circuit if the map tile is uniform
7017 // TODO: Replace with json mapgen functions.
7018 if( terrain_type == air ) {
7019 generate_uniform( grid_abs_sub_rounded, t_open_air );
7020 } else if( terrain_type == rock ) {
7021 generate_uniform( grid_abs_sub_rounded, t_rock );
7022 } else {
7023 tinymap tmp_map;
7024 tmp_map.generate( grid_abs_sub_rounded, calendar::turn );
7025 }
7026
7027 // This is the same call to MAPBUFFER as above!
7028 tmpsub = MAPBUFFER.lookup_submap( grid_abs_sub );
7029 if( tmpsub == nullptr ) {
7030 debugmsg( "failed to generate a submap at %s", grid_abs_sub.to_string() );
7031 return;
7032 }
7033 }
7034
7035 // New submap changes the content of the map and all caches must be recalculated
7042 setsubmap( gridn, tmpsub );
7043 if( !tmpsub->active_items.empty() ) {
7044 submaps_with_active_items.emplace( grid_abs_sub );
7045 }
7046 if( tmpsub->field_count > 0 ) {
7047 get_cache( grid.z ).field_cache.set( grid.x + grid.y * MAPSIZE );
7048 }
7049 // Destroy bugged no-part vehicles
7050 auto &veh_vec = tmpsub->vehicles;
7051 for( auto iter = veh_vec.begin(); iter != veh_vec.end(); ) {
7052 vehicle *veh = iter->get();
7053 if( veh->part_count() > 0 ) {
7054 // Always fix submap coordinates for easier Z-level-related operations
7055 veh->sm_pos = grid;
7056 veh->attach();
7057 iter++;
7058 } else {
7060 if( veh->tracking_on ) {
7062 }
7063 dirty_vehicle_list.erase( veh );
7064 iter = veh_vec.erase( iter );
7065 }
7066 }
7067
7068 // Update vehicle data
7069 if( update_vehicles ) {
7070 auto &map_cache = get_cache( grid.z );
7071 for( const auto &veh : tmpsub->vehicles ) {
7072 // Only add if not tracking already.
7073 if( map_cache.vehicle_list.find( veh.get() ) == map_cache.vehicle_list.end() ) {
7074 map_cache.vehicle_list.insert( veh.get() );
7075 if( !veh->loot_zones.empty() ) {
7076 map_cache.zone_vehicles.insert( veh.get() );
7077 }
7078 add_vehicle_to_cache( veh.get() );
7079 }
7080 }
7081 }
7082
7083 actualize( grid );
7084
7085 abs_sub.z = old_abs_z;
7086}
void set_suspension_cache_dirty(const int zlev)
Definition: map.h:459
void generate(const tripoint &p, const time_point &when)
Definition: mapgen.cpp:106
void actualize(const tripoint &grid)
Fast forward a submap that has just been loading into this map.
Definition: map.cpp:7406
submap * lookup_submap(const tripoint &p)
Get a submap stored in this buffer.
Definition: mapbuffer.cpp:88
Definition: map.h:2095
std::unordered_multimap< point, zone_data > loot_zones
Definition: vehicle.h:1863
int part_count() const
Definition: vehicle.cpp:7075
void attach()
Definition: vehicle.h:764
point omt_to_sm_copy(const point &p)
static void generate_uniform(const tripoint &p, const ter_id &terrain_type)
Definition: map.cpp:6975
mapbuffer MAPBUFFER
Definition: mapbuffer.cpp:40

References abs_sub, submap::active_items, actualize(), add_vehicle_to_cache(), vehicle::attach(), dbg, debugmsg, dirty_vehicle_list, active_item_cache::empty(), level_cache::field_cache, submap::field_count, generate(), generate_uniform(), get_cache(), get_nonant(), grid, Info, mapbuffer::lookup_submap(), MAPBUFFER, MAPSIZE, omt_to_sm_copy(), overmap_buffer, vehicle::part_count(), coords::coord_point< Point, Origin, Scale >::raw(), overmapbuffer::remove_vehicle(), reset_vehicle_cache(), set_floor_cache_dirty(), set_outside_cache_dirty(), set_pathfinding_cache_dirty(), set_seen_cache_dirty(), set_suspension_cache_dirty(), set_transparency_cache_dirty(), setsubmap(), vehicle::sm_pos, sm_to_omt_copy(), submaps_with_active_items, t_open_air, t_rock, overmapbuffer::ter(), tripoint::to_string(), vehicle::tracking_on, calendar::turn, submap::vehicles, tripoint::xy(), and tripoint::z.

Referenced by load(), loadn(), and shift().

◆ make_active()

void map::make_active ( item_location loc)

Update an item's active status, for example when adding hot or perishable liquid to a container.

Definition at line 4416 of file map.cpp.

4417{
4418 item *target = loc.get_item();
4419
4420 // Trust but verify, don't let stinking callers set items active when they shouldn't be.
4421 if( !target->needs_processing() ) {
4422 return;
4423 }
4424 point l;
4425 submap *const current_submap = get_submap_at( loc.position(), l );
4426 cata::colony<item> &item_stack = current_submap->get_items( l );
4428
4429 if( current_submap->active_items.empty() ) {
4431 abs_sub.y + loc.position().y / SEEY, loc.position().z ) );
4432 }
4433 current_submap->active_items.add( *iter, l );
4434}
item * get_item()
Gets the selected item or nullptr.
tripoint position() const
Returns the position where the item is found.

References abs_sub, submap::active_items, active_item_cache::add(), active_item_cache::empty(), item_location::get_item(), submap::get_items(), item_stack::get_iterator_from_pointer(), get_submap_at(), item::needs_processing(), item_location::position(), SEEX, SEEY, submaps_with_active_items, tripoint::x, tripoint::y, and tripoint::z.

Referenced by make_active(), and liquid_handler::perform_liquid_transfer().

◆ make_rubble() [1/3]

void map::make_rubble ( const tripoint p)
inline

Definition at line 1065 of file map.h.

1065 {
1066 make_rubble( p, f_rubble, false, t_dirt, false );
1067 }

References f_rubble, make_rubble(), and t_dirt.

◆ make_rubble() [2/3]

void map::make_rubble ( const tripoint p,
const furn_id rubble_type,
bool  items 
)
inline

Definition at line 1062 of file map.h.

1062 {
1063 make_rubble( p, rubble_type, items, t_dirt, false );
1064 }

References make_rubble(), and t_dirt.

◆ make_rubble() [3/3]

void map::make_rubble ( const tripoint p,
const furn_id rubble_type,
bool  items,
const ter_id floor_type,
bool  overwrite = false 
)

Generates rubble at the given location, if overwrite is true it just writes on top of what currently exists floor_type is only used if there is a non-bashable wall at the location or with overwrite = true.

Definition at line 2498 of file map.cpp.

2500{
2501 if( overwrite ) {
2502 ter_set( p, floor_type );
2503 furn_set( p, rubble_type );
2504 } else {
2505 // First see if there is existing furniture to destroy
2506 if( is_bashable_furn( p ) ) {
2507 destroy_furn( p, true );
2508 }
2509 // Leave the terrain alone unless it interferes with furniture placement
2510 if( impassable( p ) && is_bashable_ter( p ) ) {
2511 destroy( p, true );
2512 }
2513 // Check again for new terrain after potential destruction
2514 if( impassable( p ) ) {
2515 ter_set( p, floor_type );
2516 }
2517
2518 furn_set( p, rubble_type );
2519 }
2520
2521 if( !items ) {
2522 return;
2523 }
2524
2525 //Still hardcoded, but a step up from the old stuff due to being in only one place
2526 if( rubble_type == f_wreckage ) {
2527 item chunk( "steel_chunk", calendar::turn );
2528 item scrap( "scrap", calendar::turn );
2529 add_item_or_charges( p, chunk );
2530 add_item_or_charges( p, scrap );
2531 if( one_in( 5 ) ) {
2532 item pipe( "pipe", calendar::turn );
2533 item wire( "wire", calendar::turn );
2534 add_item_or_charges( p, pipe );
2535 add_item_or_charges( p, wire );
2536 }
2537 } else if( rubble_type == f_rubble_rock ) {
2538 item rock( "rock", calendar::turn );
2539 int rock_count = rng( 1, 3 );
2540 for( int i = 0; i < rock_count; i++ ) {
2541 add_item_or_charges( p, rock );
2542 }
2543 } else if( rubble_type == f_rubble ) {
2544 item splinter( "splinter", calendar::turn );
2545 int splinter_count = rng( 2, 8 );
2546 for( int i = 0; i < splinter_count; i++ ) {
2547 add_item_or_charges( p, splinter );
2548 }
2549 spawn_item( p, itype_nail, 1, rng( 20, 50 ) );
2550 }
2551}
void destroy_furn(const tripoint &p, bool silent=false)
Keeps bashing a square until there is no more furniture.
Definition: map.cpp:3643
static const itype_id itype_nail("nail")

References add_item_or_charges(), destroy(), destroy_furn(), f_rubble, f_rubble_rock, f_wreckage, furn_set(), impassable(), is_bashable_furn(), is_bashable_ter(), itype_nail, one_in(), rng(), spawn_item(), ter_set(), and calendar::turn.

Referenced by computer_session::action_irradiator(), computer_session::action_srcf_seal(), jmapgen_make_rubble::apply(), collapse_at(), draw_lab(), draw_mine(), computer_session::failure_pump_explode(), make_rubble(), mapgen_crater(), MapExtras::mx_helicopter(), and MapExtras::mx_portal().

◆ maptile_at() [1/2]

maptile map::maptile_at ( const tripoint p)

Definition at line 210 of file map.cpp.

211{
212 if( !inbounds( p ) ) {
213 return maptile( &null_submap, point_zero );
214 }
215
216 return maptile_at_internal( p );
217}
static submap null_submap
Definition: map.cpp:199

References inbounds(), maptile_at_internal(), null_submap, and point_zero.

◆ maptile_at() [2/2]

maptile map::maptile_at ( const tripoint p) const

◆ maptile_at_internal() [1/2]

maptile map::maptile_at_internal ( const tripoint p)
private

Definition at line 227 of file map.cpp.

228{
229 point l;
230 submap *const sm = get_submap_at( p, l );
231
232 return maptile( sm, l );
233}

References get_submap_at(), and coords::sm.

◆ maptile_at_internal() [2/2]

maptile map::maptile_at_internal ( const tripoint p) const
private

Definition at line 219 of file map.cpp.

220{
221 point l;
222 submap *const sm = get_submap_at( p, l );
223
224 return maptile( sm, l );
225}

References get_submap_at(), and coords::sm.

Referenced by draw(), maptile_at(), maptile_has_bounds(), process_fields_in_submap(), route(), and spread_gas().

◆ maptile_has_bounds()

std::pair< tripoint, maptile > map::maptile_has_bounds ( const tripoint p,
bool  bounds_checked 
)
private

Definition at line 180 of file map_field.cpp.

181{
182 if( bounds_checked ) {
183 // We know that the point is in bounds
184 return {p, maptile_at_internal( p )};
185 }
186
187 return {p, maptile_at( p )};
188}

References maptile_at(), and maptile_at_internal().

Referenced by get_neighbors().

◆ max_volume()

units::volume map::max_volume ( const tripoint p)

Definition at line 4207 of file map.cpp.

4208{
4209 return i_at( p ).max_volume();
4210}
units::volume max_volume() const override
Maximum volume allowed here.
Definition: map.cpp:162

References i_at(), and map_stack::max_volume().

Referenced by advanced_inventory::print_items().

◆ mod_field_age()

time_duration map::mod_field_age ( const tripoint p,
const field_type_id type,
const time_duration offset 
)

Increment/decrement age of field entry at point.

Returns
resulting age or -1_turns if not present (does not create a new field).

Definition at line 5316 of file map.cpp.

5318{
5319 return set_field_age( p, type, offset, true );
5320}
time_duration set_field_age(const tripoint &p, const field_type_id &type, const time_duration &age, bool isoffset=false)
Set age of field entry at point.
Definition: map.cpp:5327

References set_field_age(), and type.

Referenced by game::process_artifact().

◆ mod_field_intensity()

int map::mod_field_intensity ( const tripoint p,
const field_type_id type,
int  offset 
)

Increment/decrement intensity of field entry at point, creating if not present, removing if intensity becomes 0.

Returns
resulting intensity, or 0 for not present (either removed or not created at all).

Definition at line 5322 of file map.cpp.

5323{
5324 return set_field_intensity( p, type, offset, true );
5325}
int set_field_intensity(const tripoint &p, const field_type_id &type, int new_intensity, bool isoffset=false)
Set intensity of field entry at point, creating if not present, removing if intensity becomes 0.
Definition: map.cpp:5340

References set_field_intensity(), and type.

Referenced by add_splatter(), and propagate_field().

◆ monster_in_field()

void map::monster_in_field ( monster z)
protected

Definition at line 1632 of file map_field.cpp.

1633{
1634 if( z.digging() ) {
1635 // Digging monsters are immune to fields
1636 return;
1637 }
1638 if( veh_at( z.pos() ) ) {
1639 // FIXME: Immune when in a vehicle for now.
1640 return;
1641 }
1642 field &curfield = get_field( z.pos() );
1643
1644 int dam = 0;
1645 // Iterate through all field effects on this tile.
1646 // Do not remove the field with remove_field, instead set it's intensity to 0. It will be removed
1647 // later by the field processing, which will also adjust field_count accordingly.
1648 for( auto &field_list_it : curfield ) {
1649 field_entry &cur = field_list_it.second;
1650 if( !cur.is_field_alive() ) {
1651 continue;
1652 }
1653 const field_type_id cur_field_type = cur.get_field_type();
1654 if( cur_field_type == fd_web ) {
1655 if( !z.has_flag( MF_WEBWALK ) ) {
1656 z.add_effect( effect_webbed, 1_turns, num_bp, cur.get_field_intensity() );
1657 cur.set_field_intensity( 0 );
1658 }
1659 }
1660 if( cur_field_type == fd_acid ) {
1661 if( !z.flies() ) {
1662 const int d = rng( cur.get_field_intensity(), cur.get_field_intensity() * 3 );
1663 z.deal_damage( nullptr, bodypart_id( "torso" ), damage_instance( DT_ACID, d ) );
1664 z.check_dead_state();
1665 if( d > 0 ) {
1666 z.add_effect( effect_corroding, 1_turns * rng( d / 2, d * 2 ) );
1667 }
1668 }
1669
1670 }
1671 if( cur_field_type == fd_sap ) {
1672 z.moves -= cur.get_field_intensity() * 5;
1674 }
1675 if( cur_field_type == fd_sludge ) {
1676 if( !z.digs() && !z.flies() &&
1677 !z.has_flag( MF_SLUDGEPROOF ) ) {
1678 z.moves -= cur.get_field_intensity() * 300;
1679 cur.set_field_intensity( 0 );
1680 }
1681 }
1682 if( cur_field_type == fd_fire ) {
1683 // TODO: MATERIALS Use fire resistance
1684 if( z.has_flag( MF_FIREPROOF ) || z.has_flag( MF_FIREY ) ) {
1685 return;
1686 }
1687 // TODO: Replace the section below with proper json values
1689 dam += 3;
1690 }
1691 if( z.made_of( material_id( "veggy" ) ) ) {
1692 dam += 12;
1693 }
1695 dam += 20;
1696 }
1698 dam += -20;
1699 }
1700 if( z.flies() ) {
1701 dam -= 15;
1702 }
1703 dam -= z.get_armor_type( DT_HEAT, bodypart_id( "torso" ) );
1704
1705 if( cur.get_field_intensity() == 1 ) {
1706 dam += rng( 2, 6 );
1707 } else if( cur.get_field_intensity() == 2 ) {
1708 dam += rng( 6, 12 );
1709 if( !z.flies() ) {
1710 z.moves -= 20;
1711 if( dam > 0 ) {
1712 z.add_effect( effect_onfire, 1_turns * rng( dam / 2, dam * 2 ) );
1713 }
1714 }
1715 } else if( cur.get_field_intensity() == 3 ) {
1716 dam += rng( 10, 20 );
1717 if( !z.flies() || one_in( 3 ) ) {
1718 z.moves -= 40;
1719 if( dam > 0 ) {
1720 z.add_effect( effect_onfire, 1_turns * rng( dam / 2, dam * 2 ) );
1721 }
1722 }
1723 }
1724 }
1725 if( cur_field_type == fd_smoke ) {
1726 if( !z.has_flag( MF_NO_BREATHE ) ) {
1727 if( cur.get_field_intensity() == 3 ) {
1728 z.moves -= rng( 10, 20 );
1729 }
1730 // Plants suffer from smoke even worse
1731 if( z.made_of( material_id( "veggy" ) ) ) {
1732 z.moves -= rng( 1, cur.get_field_intensity() * 12 );
1733 }
1734 }
1735
1736 }
1737 if( cur_field_type == fd_tear_gas ) {
1739 if( cur.get_field_intensity() == 3 ) {
1740 z.add_effect( effect_stunned, rng( 1_minutes, 2_minutes ) );
1741 dam += rng( 4, 10 );
1742 } else if( cur.get_field_intensity() == 2 ) {
1743 z.add_effect( effect_stunned, rng( 5_turns, 10_turns ) );
1744 dam += rng( 2, 5 );
1745 } else {
1746 z.add_effect( effect_stunned, rng( 1_turns, 5_turns ) );
1747 }
1748 if( z.made_of( material_id( "veggy" ) ) ) {
1749 z.moves -= rng( cur.get_field_intensity() * 5, cur.get_field_intensity() * 12 );
1750 dam += cur.get_field_intensity() * rng( 8, 14 );
1751 }
1752 if( z.has_flag( MF_SEES ) ) {
1753 z.add_effect( effect_blind, cur.get_field_intensity() * 8_turns );
1754 }
1755 }
1756
1757 }
1758 if( cur_field_type == fd_relax_gas ) {
1760 z.add_effect( effect_stunned, rng( cur.get_field_intensity() * 4_turns,
1761 cur.get_field_intensity() * 8_turns ) );
1762 }
1763 }
1764 if( cur_field_type == fd_dazzling ) {
1765 if( z.has_flag( MF_SEES ) && !z.has_flag( MF_ELECTRONIC ) ) {
1766 z.add_effect( effect_blind, cur.get_field_intensity() * 12_turns );
1767 z.add_effect( effect_stunned, cur.get_field_intensity() * rng( 5_turns, 12_turns ) );
1768 }
1769
1770 }
1771 if( cur_field_type == fd_toxic_gas ) {
1772 if( !z.has_flag( MF_NO_BREATHE ) ) {
1773 dam += cur.get_field_intensity();
1774 z.moves -= cur.get_field_intensity();
1775 }
1776
1777 }
1778 if( cur_field_type == fd_nuke_gas ) {
1779 if( !z.has_flag( MF_NO_BREATHE ) ) {
1780 if( cur.get_field_intensity() == 3 ) {
1781 z.moves -= rng( 60, 120 );
1782 dam += rng( 30, 50 );
1783 } else if( cur.get_field_intensity() == 2 ) {
1784 z.moves -= rng( 20, 50 );
1785 dam += rng( 10, 25 );
1786 } else {
1787 z.moves -= rng( 0, 15 );
1788 dam += rng( 0, 12 );
1789 }
1790 if( z.made_of( material_id( "veggy" ) ) ) {
1791 z.moves -= rng( cur.get_field_intensity() * 5, cur.get_field_intensity() * 12 );
1792 dam *= cur.get_field_intensity();
1793 }
1794 }
1795
1796 }
1797 if( cur_field_type == fd_flame_burst ) {
1798 // TODO: MATERIALS Use fire resistance
1799 if( z.has_flag( MF_FIREPROOF ) || z.has_flag( MF_FIREY ) ) {
1800 return;
1801 }
1803 dam += 3;
1804 }
1805 if( z.made_of( material_id( "veggy" ) ) ) {
1806 dam += 12;
1807 }
1809 dam += 50;
1810 }
1812 dam += -25;
1813 }
1814 dam += rng( 0, 8 );
1815 z.moves -= 20;
1816 }
1817 if( cur_field_type == fd_electricity ) {
1818 // We don't want to increase dam, but deal a separate hit so that it can apply effects
1819 z.deal_damage( nullptr, bodypart_id( "torso" ),
1820 damage_instance( DT_ELECTRIC, rng( 1, cur.get_field_intensity() * 3 ) ) );
1821 }
1822 if( cur_field_type == fd_fatigue ) {
1823 if( rng( 0, 2 ) < cur.get_field_intensity() ) {
1824 dam += cur.get_field_intensity();
1825 teleport::teleport( z );
1826 }
1827 }
1828 if( cur_field_type == fd_incendiary ) {
1829 // TODO: MATERIALS Use fire resistance
1830 if( z.has_flag( MF_FIREPROOF ) || z.has_flag( MF_FIREY ) ) {
1831 return;
1832 }
1834 dam += 3;
1835 }
1836 if( z.made_of( material_id( "veggy" ) ) ) {
1837 dam += 12;
1838 }
1840 dam += 20;
1841 }
1843 dam += -5;
1844 }
1845
1846 if( cur.get_field_intensity() == 1 ) {
1847 dam += rng( 2, 6 );
1848 } else if( cur.get_field_intensity() == 2 ) {
1849 dam += rng( 6, 12 );
1850 z.moves -= 20;
1851 if( !z.made_of( LIQUID ) && !z.made_of_any( Creature::cmat_flameres ) ) {
1852 z.add_effect( effect_onfire, rng( 8_turns, 12_turns ) );
1853 }
1854 } else if( cur.get_field_intensity() == 3 ) {
1855 dam += rng( 10, 20 );
1856 z.moves -= 40;
1857 if( !z.made_of( LIQUID ) && !z.made_of_any( Creature::cmat_flameres ) ) {
1858 z.add_effect( effect_onfire, rng( 12_turns, 16_turns ) );
1859 }
1860 }
1861 }
1862 if( cur_field_type == fd_fungal_haze ) {
1863 if( !z.type->in_species( FUNGUS ) &&
1864 !z.type->has_flag( MF_NO_BREATHE ) &&
1865 !z.make_fungus() ) {
1866 // Don't insta-kill jabberwocks, that's silly
1867 const int intensity = cur.get_field_intensity();
1868 z.moves -= rng( 10 * intensity, 30 * intensity );
1869 dam += rng( 0, 10 * intensity );
1870 }
1871 }
1872 if( cur_field_type == fd_fungicidal_gas ) {
1873 if( z.type->in_species( FUNGUS ) ) {
1874 const int intensity = cur.get_field_intensity();
1875 z.moves -= rng( 10 * intensity, 30 * intensity );
1876 dam += rng( 4, 7 * intensity );
1877 }
1878 }
1879 if( cur_field_type == fd_insecticidal_gas ) {
1880 if( z.type->in_species( INSECT ) || z.type->in_species( SPIDER ) ) {
1881 const int intensity = cur.get_field_intensity();
1882 z.moves -= rng( 10 * intensity, 30 * intensity );
1883 dam += rng( 4, 7 * intensity );
1884 }
1885 }
1886 }
1887
1888 if( dam > 0 ) {
1889 z.apply_damage( nullptr, bodypart_id( "torso" ), dam, true );
1890 z.check_dead_state();
1891 }
1892}
static const std::set< material_id > cmat_flammable
Definition: creature.h:477
virtual dealt_damage_instance deal_damage(Creature *source, bodypart_id bp, const damage_instance &dam)
Deals the damage via an attack.
Definition: creature.cpp:879
static const std::set< material_id > cmat_flesh
Definition: creature.h:475
int moves
Definition: creature.h:569
static const std::set< material_id > cmat_fleshnveg
Definition: creature.h:476
static const std::set< material_id > cmat_flameres
Definition: creature.h:478
bool has_flag(m_flag f) const override
Definition: monster.cpp:889
bool digs() const
Definition: monster.cpp:931
bool made_of_any(const std::set< material_id > &ms) const override
Definition: monster.cpp:983
void add_effect(const efftype_id &eff_id, const time_duration &dur, const bodypart_str_id &bp, int intensity=0, bool force=false, bool deferred=false) override
Performs any monster-specific modifications to the arguments before passing to Creature::add_effect()...
Definition: monster.cpp:1832
bool make_fungus()
Makes this monster into a fungus version Returns false if no such monster exists Returns true if mons...
Definition: monster.cpp:2624
const tripoint & pos() const override
Definition: monster.cpp:256
bool made_of(const material_id &m) const override
Definition: monster.cpp:978
const mtype * type
Definition: monster.h:481
int get_armor_type(damage_type dt, bodypart_id bp) const override
Definition: monster.cpp:1893
bool flies() const
Definition: monster.cpp:936
bool digging() const override
Definition: monster.cpp:921
@ DT_ELECTRIC
Definition: damage.h:30
@ DT_HEAT
Definition: damage.h:28
field_type_id fd_incendiary
Definition: field_type.cpp:372
field_type_id fd_toxic_gas
Definition: field_type.cpp:347
field_type_id fd_tear_gas
Definition: field_type.cpp:348
field_type_id fd_sludge
Definition: field_type.cpp:344
field_type_id fd_nuke_gas
Definition: field_type.cpp:349
field_type_id fd_dazzling
Definition: field_type.cpp:361
field_type_id fd_electricity
Definition: field_type.cpp:353
field_type_id fd_fungal_haze
Definition: field_type.cpp:374
field_type_id fd_smoke
Definition: field_type.cpp:346
field_type_id fd_sap
Definition: field_type.cpp:343
field_type_id fd_fungicidal_gas
Definition: field_type.cpp:383
field_type_id fd_acid
Definition: field_type.cpp:342
field_type_id fd_flame_burst
Definition: field_type.cpp:352
field_type_id fd_relax_gas
Definition: field_type.cpp:373
field_type_id fd_fatigue
Definition: field_type.cpp:354
field_type_id fd_insecticidal_gas
Definition: field_type.cpp:384
static const efftype_id effect_blind("blind")
static const species_id FUNGUS("FUNGUS")
static const species_id INSECT("INSECT")
static const efftype_id effect_webbed("webbed")
static const efftype_id effect_stunned("stunned")
static const species_id SPIDER("SPIDER")
static const efftype_id effect_onfire("onfire")
@ MF_SEES
Definition: mtype.h:67
@ MF_FIREY
Definition: mtype.h:103
@ MF_WEBWALK
Definition: mtype.h:85
@ MF_FIREPROOF
Definition: mtype.h:99
@ MF_SLUDGEPROOF
Definition: mtype.h:100
@ MF_ELECTRONIC
Definition: mtype.h:105
@ MF_NO_BREATHE
Definition: mtype.h:123
bool teleport(Creature &critter, int min_distance=2, int max_distance=12, bool safe=false, bool add_teleglow=true)
Teleports a creature to a tile within min_distance and max_distance tiles.
Definition: teleport.cpp:24
bool has_flag(m_flag flag) const
Definition: mtype.cpp:75
bool in_species(const species_id &spec) const
Definition: mtype.cpp:122

References monster::add_effect(), monster::apply_damage(), Creature::check_dead_state(), Creature::cmat_flameres, Creature::cmat_flammable, Creature::cmat_flesh, Creature::cmat_fleshnveg, Creature::deal_damage(), monster::digging(), monster::digs(), DT_ACID, DT_ELECTRIC, DT_HEAT, effect_blind, effect_corroding, effect_onfire, effect_stunned, effect_webbed, fd_acid, fd_dazzling, fd_electricity, fd_fatigue, fd_fire, fd_flame_burst, fd_fungal_haze, fd_fungicidal_gas, fd_incendiary, fd_insecticidal_gas, fd_nuke_gas, fd_relax_gas, fd_sap, fd_sludge, fd_smoke, fd_tear_gas, fd_toxic_gas, fd_web, monster::flies(), FUNGUS, monster::get_armor_type(), get_field(), field_entry::get_field_intensity(), field_entry::get_field_type(), monster::has_flag(), mtype::has_flag(), mtype::in_species(), INSECT, field_entry::is_field_alive(), LIQUID, monster::made_of(), monster::made_of_any(), monster::make_fungus(), MF_ELECTRONIC, MF_FIREPROOF, MF_FIREY, MF_NO_BREATHE, MF_SEES, MF_SLUDGEPROOF, MF_WEBWALK, Creature::moves, num_bp, one_in(), monster::pos(), rng(), field_entry::set_field_intensity(), SPIDER, teleport::teleport(), monster::type, and veh_at().

Referenced by creature_in_field().

◆ mop_spills()

bool map::mop_spills ( const tripoint p)

Remove moppable fields/items at this location.

Parameters
pthe location
Returns
true if anything moppable was there, false otherwise.

Definition at line 2794 of file map.cpp.

2795{
2796 bool retval = false;
2797
2798 if( !has_flag( "LIQUIDCONT", p ) && !has_flag( "SEALED", p ) ) {
2799 auto items = i_at( p );
2800 auto new_end = std::remove_if( items.begin(), items.end(), []( const item & it ) {
2801 return it.made_of( LIQUID );
2802 } );
2803 retval = new_end != items.end();
2804 while( new_end != items.end() ) {
2805 new_end = items.erase( new_end );
2806 }
2807 }
2808
2809 field &fld = field_at( p );
2810 static const std::vector<field_type_id> to_check = {
2811 fd_blood,
2819 fd_bile,
2820 fd_slime,
2821 fd_sludge
2822 };
2823 for( field_type_id fid : to_check ) {
2824 retval |= fld.remove_field( fid );
2825 }
2826
2827 if( const optional_vpart_position vp = veh_at( p ) ) {
2828 vehicle *const veh = &vp->vehicle();
2829 std::vector<int> parts_here = veh->parts_at_relative( vp->mount(), true );
2830 for( auto &elem : parts_here ) {
2831 if( veh->part( elem ).blood > 0 ) {
2832 veh->part( elem ).blood = 0;
2833 retval = true;
2834 }
2835 //remove any liquids that somehow didn't fall through to the ground
2836 vehicle_stack here = veh->get_items( elem );
2837 auto new_end = std::remove_if( here.begin(), here.end(), []( const item & it ) {
2838 return it.made_of( LIQUID );
2839 } );
2840 retval |= ( new_end != here.end() );
2841 while( new_end != here.end() ) {
2842 new_end = here.erase( new_end );
2843 }
2844 }
2845 } // if veh != 0
2846 return retval;
2847}
bool remove_field(const field_type_id &field_to_remove)
Removes the field entry with a type equal to the field_type_id parameter.
Definition: field.cpp:219
iterator erase(const_iterator it) override
Definition: vehicle.cpp:230
std::vector< int > parts_at_relative(const point &dp, bool use_cache) const
Definition: vehicle.cpp:2416
field_type_id fd_gibs_insect
Definition: field_type.cpp:365
field_type_id fd_blood_insect
Definition: field_type.cpp:363
field_type_id fd_bile
Definition: field_type.cpp:337
field_type_id fd_blood_invertebrate
Definition: field_type.cpp:364
field_type_id fd_blood_veggy
Definition: field_type.cpp:362
field_type_id fd_gibs_veggy
Definition: field_type.cpp:339
field_type_id fd_blood
Definition: field_type.cpp:336
field_type_id fd_slime
Definition: field_type.cpp:341
field_type_id fd_gibs_invertebrate
Definition: field_type.cpp:366
field_type_id fd_gibs_flesh
Definition: field_type.cpp:338

References item_stack::begin(), vehicle_part::blood, item_stack::end(), vehicle_stack::erase(), fd_bile, fd_blood, fd_blood_insect, fd_blood_invertebrate, fd_blood_veggy, fd_gibs_flesh, fd_gibs_insect, fd_gibs_invertebrate, fd_gibs_veggy, fd_slime, fd_sludge, field_at(), vehicle::get_items(), has_flag(), i_at(), vehicle::part(), vehicle::parts_at_relative(), field::remove_field(), veh_at(), and vehicle::vehicle().

◆ move_cost() [1/2]

int map::move_cost ( const point p,
const vehicle ignored_vehicle = nullptr 
) const
inline

Definition at line 628 of file map.h.

628 {
629 return move_cost( tripoint( p, abs_sub.z ), ignored_vehicle );
630 }

References abs_sub, move_cost(), and tripoint::z.

◆ move_cost() [2/2]

int map::move_cost ( const tripoint p,
const vehicle ignored_vehicle = nullptr 
) const

Calculate the cost to move past the tile at p.

The move cost is determined by various obstacles, such as terrain, vehicles and furniture.

Note
Movement costs for players and zombies both use this function.
Returns
The return value is interpreted as follows:
Move Cost Meaning
0 Impassable. Use passable/impassable to check for this.
n > 0 x*n turns to move past this

Definition at line 1780 of file map.cpp.

1781{
1782 if( !inbounds( p ) ) {
1783 return 0;
1784 }
1785
1786 const furn_t &furniture = furn( p ).obj();
1787 const ter_t &terrain = ter( p ).obj();
1788 const optional_vpart_position vp = veh_at( p );
1789 vehicle *const veh = ( !vp || &vp->vehicle() == ignored_vehicle ) ? nullptr : &vp->vehicle();
1790 const int part = veh ? vp->part_index() : -1;
1791
1792 return move_cost_internal( furniture, terrain, veh, part );
1793}
int move_cost_internal(const furn_t &furniture, const ter_t &terrain, const vehicle *veh, int vpart) const
Internal versions of public functions to avoid checking same variables multiple times.
Definition: map.cpp:1743

References furn(), furniture, inbounds(), move_cost_internal(), int_id< T >::obj(), ter(), terrain, and veh_at().

Referenced by Character::base_comfort_value(), activity_handlers::burrow_finish(), combined_movecost(), draw_mine(), game::grabbed_veh_move(), place_trap_actor::is_allowed(), is_solid_neighbor(), mine_activity(), npc::move_away_from(), move_cost(), obstacle_coverage(), passable(), activity_handlers::pickaxe_finish(), game::print_terrain_info(), reachable_flood_steps(), deploy_furn_actor::use(), and game::walk_move().

◆ move_cost_internal()

int map::move_cost_internal ( const furn_t furniture,
const ter_t terrain,
const vehicle veh,
int  vpart 
) const
private

Internal versions of public functions to avoid checking same variables multiple times.

They lack safety checks, because their callers already do those.

Definition at line 1743 of file map.cpp.

1745{
1746 if( terrain.movecost == 0 || ( furniture.id && furniture.movecost < 0 ) ) {
1747 return 0;
1748 }
1749
1750 if( veh != nullptr ) {
1751 const vpart_position vp( const_cast<vehicle &>( *veh ), vpart );
1752 if( vp.obstacle_at_part() ) {
1753 return 0;
1754 } else if( vp.part_with_feature( VPFLAG_AISLE, true ) ) {
1755 return 2;
1756 } else {
1757 return 8;
1758 }
1759 }
1760
1761 if( furniture.id ) {
1762 return std::max( terrain.movecost + furniture.movecost, 0 );
1763 }
1764
1765 return std::max( terrain.movecost, 0 );
1766}

References furniture, vpart_position::obstacle_at_part(), vpart_position::part_with_feature(), terrain, and VPFLAG_AISLE.

Referenced by move_cost(), route(), and update_pathfinding_cache().

◆ move_cost_ter_furn() [1/2]

int map::move_cost_ter_furn ( const point p) const
inline

Definition at line 645 of file map.h.

645 {
646 return move_cost_ter_furn( tripoint( p, abs_sub.z ) );
647 }
int move_cost_ter_furn(const tripoint &p) const
Similar behavior to move_cost(), but ignores vehicles.
Definition: map.cpp:1805

References abs_sub, move_cost_ter_furn(), and tripoint::z.

◆ move_cost_ter_furn() [2/2]

int map::move_cost_ter_furn ( const tripoint p) const

Similar behavior to move_cost(), but ignores vehicles.

Definition at line 1805 of file map.cpp.

1806{
1807 if( !inbounds( p ) ) {
1808 return 0;
1809 }
1810
1811 point l;
1812 submap *const current_submap = get_submap_at( p, l );
1813
1814 const int tercost = current_submap->get_ter( l ).obj().movecost;
1815 if( tercost == 0 ) {
1816 return 0;
1817 }
1818
1819 const int furncost = current_submap->get_furn( l ).obj().movecost;
1820 if( furncost < 0 ) {
1821 return 0;
1822 }
1823
1824 const int cost = tercost + furncost;
1825 return cost > 0 ? cost : 0;
1826}

References submap::get_furn(), get_submap_at(), submap::get_ter(), inbounds(), map_data_common_t::movecost, and int_id< T >::obj().

Referenced by move_cost_ter_furn(), vehicle::part_collision(), passable_ter_furn(), and vehicle_wheel_traction().

◆ move_vehicle()

vehicle * map::move_vehicle ( vehicle veh,
const tripoint dp,
const tileray facing 
)

Definition at line 520 of file map.cpp.

521{
522 if( dp == tripoint_zero ) {
523 debugmsg( "Empty displacement vector" );
524 return &veh;
525 } else if( std::abs( dp.x ) > 1 || std::abs( dp.y ) > 1 || std::abs( dp.z ) > 1 ) {
526 debugmsg( "Invalid displacement vector: %d, %d, %d", dp.x, dp.y, dp.z );
527 return &veh;
528 }
529 // Split the movement into horizontal and vertical for easier processing
530 if( dp.xy() != point_zero && dp.z != 0 ) {
531 vehicle *const new_pointer = move_vehicle( veh, tripoint( dp.xy(), 0 ), facing );
532 if( !new_pointer ) {
533 return nullptr;
534 }
535
536 vehicle *const result = move_vehicle( *new_pointer, tripoint( 0, 0, dp.z ), facing );
537 if( !result ) {
538 return nullptr;
539 }
540
541 result->is_falling = false;
542 return result;
543 }
544 const bool vertical = dp.z != 0;
545 // Ensured by the splitting above
546 assert( vertical == ( dp.xy() == point_zero ) );
547
548 const int target_z = dp.z + veh.sm_pos.z;
549 if( target_z < -OVERMAP_DEPTH || target_z > OVERMAP_HEIGHT ) {
550 return &veh;
551 }
552
553 veh.precalc_mounts( 1, veh.skidding ? veh.turn_dir : facing.dir(), veh.pivot_point() );
554
555 // cancel out any movement of the vehicle due only to a change in pivot
556 tripoint dp1 = dp - veh.pivot_displacement();
557
558 if( !vertical ) {
559 veh.adjust_zlevel( 1, dp1 );
560 }
561
562 int impulse = 0;
563
564 std::vector<veh_collision> collisions;
565
566 // Find collisions
567 // Velocity of car before collision
568 // Split into vertical and horizontal movement
569 const int &coll_velocity = vertical ? veh.vertical_velocity : veh.velocity;
570 const int velocity_before = coll_velocity;
571 if( velocity_before == 0 && !veh.is_rotorcraft() && !veh.is_flying_in_air() ) {
572 debugmsg( "%s tried to move %s with no velocity",
573 veh.name, vertical ? "vertically" : "horizontally" );
574 return &veh;
575 }
576
577 bool veh_veh_coll_flag = false;
578 // Try to collide multiple times
579 size_t collision_attempts = 10;
580 do {
581 collisions.clear();
582 veh.collision( collisions, dp1, false );
583
584 // Vehicle collisions
585 std::map<vehicle *, std::vector<veh_collision> > veh_collisions;
586 for( auto &coll : collisions ) {
587 if( coll.type != veh_coll_veh ) {
588 continue;
589 }
590
591 veh_veh_coll_flag = true;
592 // Only collide with each vehicle once
593 veh_collisions[ static_cast<vehicle *>( coll.target ) ].push_back( coll );
594 }
595
596 for( auto &pair : veh_collisions ) {
597 impulse += vehicle_vehicle_collision( veh, *pair.first, pair.second );
598 }
599
600 // Non-vehicle collisions
601 for( const auto &coll : collisions ) {
602 if( coll.type == veh_coll_veh ) {
603 continue;
604 }
605 if( coll.part > veh.part_count() ||
606 veh.part( coll.part ).removed ) {
607 continue;
608 }
609
610 const point &collision_point = veh.part( coll.part ).mount;
611 const int coll_dmg = coll.imp;
612 // Shock damage, if the target part is a rotor treat as an aimed hit.
613 if( veh.part_info( coll.part ).rotor_diameter() > 0 ) {
614 veh.damage( coll.part, coll_dmg, DT_BASH, true );
615 } else {
616 impulse += coll_dmg;
617 veh.damage( coll.part, coll_dmg, DT_BASH );
618 veh.damage_all( coll_dmg / 2, coll_dmg, DT_BASH, collision_point );
619 }
620 }
621
622 // prevent vehicle bouncing after the first collision
623 if( vertical && velocity_before < 0 && coll_velocity > 0 ) {
624 veh.vertical_velocity = 0; // also affects `coll_velocity` and thus exits the loop
625 }
626
627 } while( collision_attempts-- > 0 && coll_velocity != 0 &&
628 sgn( coll_velocity ) == sgn( velocity_before ) &&
629 !collisions.empty() && !veh_veh_coll_flag );
630
631 const int velocity_after = coll_velocity;
632 bool can_move = velocity_after != 0 && sgn( velocity_after ) == sgn( velocity_before );
633 if( dp.z != 0 && veh.is_rotorcraft() ) {
634 can_move = true;
635 }
636 units::angle coll_turn = 0_degrees;
637 if( impulse > 0 ) {
638 coll_turn = shake_vehicle( veh, velocity_before, facing.dir() );
639 veh.stop_autodriving();
640 const int volume = std::min<int>( 100, std::sqrt( impulse ) );
641 // TODO: Center the sound at weighted (by impulse) average of collisions
643 false, "smash_success", "hit_vehicle" );
644 }
645
646 if( veh_veh_coll_flag ) {
647 // Break here to let the hit vehicle move away
648 return nullptr;
649 }
650
651 // If not enough wheels, mess up the ground a bit.
652 if( !vertical && !veh.valid_wheel_config() && !veh.is_in_water() && !veh.is_flying_in_air() &&
653 dp.z == 0 ) {
654 veh.velocity += veh.velocity < 0 ? 2000 : -2000;
655 for( const auto &p : veh.get_points() ) {
656 const ter_id &pter = ter( p );
657 if( pter == t_dirt || pter == t_grass ) {
658 ter_set( p, t_dirtmound );
659 }
660 }
661 }
662
663 const units::angle last_turn_dec = 1_degrees;
664 if( veh.last_turn < 0_degrees ) {
665 veh.last_turn += last_turn_dec;
666 if( veh.last_turn > -last_turn_dec ) {
667 veh.last_turn = 0_degrees;
668 }
669 } else if( veh.last_turn > 0_degrees ) {
670 veh.last_turn -= last_turn_dec;
671 if( veh.last_turn < last_turn_dec ) {
672 veh.last_turn = 0_degrees;
673 }
674 }
675
676 Character &player_character = get_player_character();
677 const bool seen = sees_veh( player_character, veh, false );
678
679 if( can_move || ( vertical && veh.is_falling ) ) {
680 // Accept new direction
681 if( veh.skidding ) {
682 veh.face.init( veh.turn_dir );
683 } else {
684 veh.face = facing;
685 }
686
687 veh.move = facing;
688 if( coll_turn != 0_degrees ) {
689 veh.skidding = true;
690 veh.turn( coll_turn );
691 }
692 veh.on_move();
693 // Actually change position
694 displace_vehicle( veh, dp1 );
695 veh.shift_zlevel();
696 } else if( !vertical ) {
697 veh.stop();
698 }
700 // If the PC is in the currently moved vehicle, adjust the
701 // view offset.
702 if( g->u.controlling_vehicle && veh_pointer_or_null( veh_at( g->u.pos() ) ) == &veh ) {
703 g->calc_driving_offset( &veh );
704 if( veh.skidding && can_move ) {
705 // TODO: Make skid recovery in air hard
707 }
708 }
709 // Now we're gonna handle traps we're standing on (if we're still moving).
710 if( !vertical && can_move ) {
711 const auto wheel_indices = veh.wheelcache; // Don't use a reference here, it causes a crash.
712
713 // Values to deal with crushing items.
714 // The math needs to be floating-point to work, so the values might as well be.
715 const float vehicle_grounded_wheel_area = static_cast<int>( vehicle_wheel_traction( veh, true ) );
716 const float weight_to_damage_factor = 0.05; // Nobody likes a magic number.
717 const float vehicle_mass_kg = to_kilogram( veh.total_mass() );
718
719 for( auto &w : wheel_indices ) {
720 const tripoint wheel_p = veh.global_part_pos3( w );
721 if( one_in( 2 ) && displace_water( wheel_p ) ) {
722 sounds::sound( wheel_p, 4, sounds::sound_t::movement, _( "splash!" ), false,
723 "environment", "splash" );
724 }
725
726 veh.handle_trap( wheel_p, w );
727 if( !has_flag( "SEALED", wheel_p ) ) {
728 const float wheel_area = veh.part( w ).wheel_area();
729
730 // Damage is calculated based on the weight of the vehicle,
731 // The area of it's wheels, and the area of the wheel running over the items.
732 // This number is multiplied by weight_to_damage_factor to get reasonable results, damage-wise.
733 const int wheel_damage = static_cast<int>( ( ( wheel_area / vehicle_grounded_wheel_area ) *
734 vehicle_mass_kg ) * weight_to_damage_factor );
735
736 //~ %1$s: vehicle name
737 smash_items( wheel_p, wheel_damage, string_format( _( "weight of %1$s" ), veh.disp_name() ),
738 false );
739 }
740 }
741 }
742 if( veh.is_towing() ) {
743 veh.do_towing_move();
744 // veh.do_towing_move() may cancel towing, so we need to recheck is_towing here
745 if( veh.is_towing() && veh.tow_data.get_towed()->tow_cable_too_far() ) {
746 add_msg( m_info, _( "A towing cable snaps off of %s." ),
747 veh.tow_data.get_towed()->disp_name() );
748 veh.tow_data.get_towed()->invalidate_towing( true );
749 }
750 }
751 // Redraw scene, but only if the player is not engaged in an activity and
752 // the vehicle was seen before or after the move.
753 if( !player_character.activity && ( seen || sees_veh( player_character, veh, true ) ) ) {
754 g->invalidate_main_ui_adaptor();
758 }
759 return &veh;
760}
player_activity activity
Definition: character.h:1516
float vehicle_wheel_traction(const vehicle &veh, bool ignore_movement_modifiers=false) const
void smash_items(const tripoint &p, int power, const std::string &cause_message, bool do_destroy)
Tries to smash the items at the given tripoint.
Definition: map.cpp:2983
bool displace_vehicle(vehicle &veh, const tripoint &dp)
Definition: map.cpp:1119
bool displace_water(const tripoint &dp)
Definition: map.cpp:1279
units::angle shake_vehicle(vehicle &veh, int velocity_before, units::angle direction)
vehicle * move_vehicle(vehicle &veh, const tripoint &dp, const tileray &facing)
Definition: map.cpp:520
float vehicle_vehicle_collision(vehicle &veh, vehicle &veh2, const std::vector< veh_collision > &collisions)
Definition: map.cpp:762
void init(const point &ad)
Definition: tileray.cpp:27
vehicle * get_towed() const
Definition: vehicle.h:158
void damage_all(int dmg1, int dmg2, damage_type type, const point &impact)
Definition: vehicle.cpp:6442
void turn(units::angle deg)
const point & pivot_point() const
Definition: vehicle.cpp:5826
void adjust_zlevel(int idir=0, const tripoint &offset=tripoint_zero)
bool is_rotorcraft() const
is the vehicle flying? is it a rotorcraft?
Definition: vehicle.cpp:4197
std::set< tripoint > & get_points(bool force_refresh=false)
Definition: vehicle.cpp:6758
bool skidding
Definition: vehicle.h:1999
units::angle last_turn
Definition: vehicle.h:1929
void precalc_mounts(int idir, units::angle dir, const point &pivot)
Definition: vehicle.cpp:3150
bool is_towing() const
Definition: vehicle.cpp:6034
int vertical_velocity
Definition: vehicle.h:1922
int velocity
Definition: vehicle.h:1918
bool valid_wheel_config() const
Definition: vehicle.cpp:4459
units::mass total_mass() const
Definition: vehicle.cpp:3306
std::vector< int > wheelcache
Definition: vehicle.h:1818
void check_falling_or_floating()
bool is_flying_in_air() const
Definition: vehicle.cpp:4207
towing_data tow_data
Definition: vehicle.h:1944
int damage(int p, int dmg, damage_type type=DT_BASH, bool aimed=true)
Definition: vehicle.cpp:6363
bool is_in_water(bool deep_water=false) const
is the vehicle mostly in water or mostly on fairly dry land?
Definition: vehicle.cpp:4222
void possibly_recover_from_skid()
tileray move
Definition: vehicle.h:1950
void stop_autodriving(bool apply_brakes=true)
bool collision(std::vector< veh_collision > &colls, const tripoint &dp, bool just_detect, bool bash_floor=false)
bool tow_cable_too_far() const
Definition: vehicle.cpp:6163
std::string disp_name() const
void handle_trap(const tripoint &p, int part)
bool is_falling
Definition: vehicle.h:2005
void shift_zlevel()
units::angle turn_dir
Definition: vehicle.h:1927
point pivot_displacement() const
Definition: vehicle.cpp:3344
void do_towing_move()
Definition: vehicle.cpp:5935
void on_move()
Definition: vehicle.cpp:5276
int rotor_diameter() const
Definition: veh_type.cpp:908
@ m_info
Definition: enums.h:265
constexpr int sgn(const T x)
Definition: enums.h:8
static bool sees_veh(const Creature &c, vehicle &veh, bool force_recalc)
Definition: map.cpp:512
void redraw_invalidated()
Redraw all invalidated windows without invalidating the top window.
Definition: ui_manager.cpp:394
quantity< int, volume_in_milliliter_tag > volume
Definition: units_volume.h:16
constexpr value_type to_kilogram(const quantity< value_type, mass_in_milligram_tag > &v)
Definition: units_mass.h:73
void refresh_display()
Make changes made to the display visible to the user immediately.
static constexpr tripoint tripoint_zero
Definition: point.h:273
int wheel_area() const
Get wheel diameter times wheel width (inches^2) or return 0 if part is not wheel.
bool removed
true if this part is removed.
Definition: vehicle.h:410
point mount
mount point: x is on the forward/backward axis, y is on the left/right axis
Definition: vehicle.h:367
@ veh_coll_veh
Definition: vehicle.h:101

References _, Character::activity, add_msg(), vehicle::adjust_zlevel(), vehicle::check_falling_or_floating(), vehicle::collision(), sounds::combat, vehicle::damage(), vehicle::damage_all(), debugmsg, tileray::dir(), vehicle::disp_name(), displace_vehicle(), displace_water(), vehicle::do_towing_move(), DT_BASH, vehicle::face, g, get_player_character(), vehicle::get_points(), towing_data::get_towed(), vehicle::global_part_pos3(), vehicle::global_pos3(), vehicle::handle_trap(), has_flag(), tileray::init(), inp_mngr, vehicle::invalidate_towing(), vehicle::is_falling, vehicle::is_flying_in_air(), vehicle::is_in_water(), vehicle::is_rotorcraft(), vehicle::is_towing(), vehicle::last_turn, m_info, vehicle_part::mount, vehicle::move, move_vehicle(), sounds::movement, vehicle::name, vehicle::on_move(), one_in(), OVERMAP_HEIGHT, vehicle::part(), vehicle::part_count(), vehicle::part_info(), vehicle::pivot_displacement(), vehicle::pivot_point(), point_zero, vehicle::possibly_recover_from_skid(), vehicle::precalc_mounts(), input_manager::pump_events(), ui_manager::redraw_invalidated(), refresh_display(), vehicle_part::removed, vpart_info::rotor_diameter(), sees_veh(), sgn(), shake_vehicle(), vehicle::shift_zlevel(), vehicle::skidding, vehicle::sm_pos, smash_items(), sounds::sound(), vehicle::stop(), vehicle::stop_autodriving(), string_format(), t_dirt, t_dirtmound, t_grass, ter(), ter_set(), units::to_kilogram(), vehicle::total_mass(), vehicle::tow_cable_too_far(), vehicle::tow_data, tripoint_zero, vehicle::turn(), vehicle::turn_dir, vehicle::valid_wheel_config(), veh_at(), veh_coll_veh, veh_pointer_or_null(), vehicle_vehicle_collision(), vehicle_wheel_traction(), vehicle::velocity, vehicle::vertical_velocity, vehicle_part::wheel_area(), vehicle::wheelcache, tripoint::x, tripoint::xy(), tripoint::y, and tripoint::z.

Referenced by vehicle::act_on_map(), and move_vehicle().

◆ name() [1/2]

std::string map::name ( const point p)
inline

Definition at line 844 of file map.h.

844 {
845 return name( tripoint( p, abs_sub.z ) );
846 }

References abs_sub, name(), and tripoint::z.

◆ name() [2/2]

◆ obscured_by_vehicle_rotation()

bool map::obscured_by_vehicle_rotation ( const tripoint from,
const tripoint to 
) const

Checks if a rotated vehicle is blocking diagonal vision, tripoints must be adjacent.

Definition at line 6519 of file map.cpp.

6520{
6521 if( !inbounds( from ) || !inbounds( to ) ) {
6522 return false;
6523 }
6524
6525 if( from.z != to.z ) {
6526 //Split it into two checks, one for each z level
6527 tripoint flattened = {from.xy(), to.z};
6528 if( obscured_by_vehicle_rotation( flattened, to ) ) {
6529 return true;
6530 }
6531 }
6532
6533 point delta = to.xy() - from.xy();
6534
6535 auto cache = get_cache( from.z ).vehicle_obscured_cache;
6536
6537 if( delta == point_north_west ) {
6538 return cache[from.x][from.y].nw;
6539 }
6540
6541 if( delta == point_north_east ) {
6542 return cache[from.x][from.y].ne;
6543 }
6544
6545 if( delta == point_south_west ) {
6546 return cache[to.x][to.y].ne;
6547 }
6548 if( delta == point_south_east ) {
6549 return cache[to.x][to.y].nw;
6550 }
6551
6552 return false;
6553}
bool obscured_by_vehicle_rotation(const tripoint &from, const tripoint &to) const
Checks if a rotated vehicle is blocking diagonal vision, tripoints must be adjacent.
Definition: map.cpp:6519
bool nw
Definition: map.h:297
diagonal_blocks vehicle_obscured_cache[MAPSIZE_X][MAPSIZE_Y]
Definition: map.h:336

References get_cache(), inbounds(), diagonal_blocks::nw, obscured_by_vehicle_rotation(), point_north_east, point_north_west, point_south_east, point_south_west, level_cache::vehicle_obscured_cache, tripoint::x, tripoint::xy(), tripoint::y, and tripoint::z.

Referenced by obscured_by_vehicle_rotation(), mattack::riotbot(), Creature::sees(), and sees().

◆ obstacle_coverage()

int map::obstacle_coverage ( const tripoint loc1,
const tripoint loc2 
) const

Returns coverage of target in relation to the observer.

Target is loc2, observer is loc1. First tile from the target is an obstacle, which has the coverage value. If there's no obstacle adjacent to the target - no coverage.

Definition at line 6217 of file map.cpp.

6218{
6219 // Can't hide if you are standing on furniture, or non-flat slowing-down terrain tile.
6220 if( furn( loc2 ).obj().id || ( move_cost( loc2 ) > 2 && !has_flag_ter( TFLAG_FLAT, loc2 ) ) ) {
6221 return 0;
6222 }
6223 const point a( std::abs( loc1.x - loc2.x ) * 2, std::abs( loc1.y - loc2.y ) * 2 );
6224 int offset = std::min( a.x, a.y ) - ( std::max( a.x, a.y ) / 2 );
6225 tripoint obstaclepos;
6226 bresenham( loc2, loc1, offset, 0, [&obstaclepos]( const tripoint & new_point ) {
6227 // Only adjacent tile between you and enemy is checked for cover.
6228 obstaclepos = new_point;
6229 return false;
6230 } );
6231 if( const auto obstacle_f = furn( obstaclepos ) ) {
6232 return obstacle_f->coverage;
6233 }
6234 if( const auto vp = veh_at( obstaclepos ) ) {
6235 if( vp->obstacle_at_part() ) {
6236 return 60;
6237 } else if( !vp->part_with_feature( VPFLAG_AISLE, true ) ) {
6238 return 45;
6239 }
6240 }
6241 return ter( obstaclepos )->coverage;
6242}
@ TFLAG_FLAT
Definition: mapdata.h:317

References a, bresenham(), map_data_common_t::coverage, furn(), has_flag_ter(), move_cost(), ter(), TFLAG_FLAT, veh_at(), VPFLAG_AISLE, tripoint::x, and tripoint::y.

Referenced by Creature::sees().

◆ obstacle_name()

std::string map::obstacle_name ( const tripoint p)

Returns the name of the obstacle at p that might be blocking movement/projectiles/etc.

Note that this only accounts for vehicles, terrain, and furniture.

Definition at line 1335 of file map.cpp.

1336{
1337 if( const cata::optional<vpart_reference> vp = veh_at( p ).obstacle_at_part() ) {
1338 return vp->info().name();
1339 }
1340 return name( p );
1341}

References name(), and veh_at().

Referenced by mattack::longswipe(), avatar_action::move(), and teleport::teleport().

◆ obstructed_by_vehicle_rotation()

bool map::obstructed_by_vehicle_rotation ( const tripoint from,
const tripoint to 
) const

Checks if a rotated vehicle is blocking diagonal movement, tripoints must be adjacent.

Definition at line 6482 of file map.cpp.

6483{
6484 if( !inbounds( from ) || !inbounds( to ) ) {
6485 return false;
6486 }
6487
6488 if( from.z != to.z ) {
6489 //Split it into two checks, one for each z level
6490 tripoint flattened = {from.xy(), to.z};
6491 if( obstructed_by_vehicle_rotation( flattened, to ) ) {
6492 return true;
6493 }
6494 }
6495
6496 point delta = to.xy() - from.xy();
6497
6498 auto cache = get_cache( from.z ).vehicle_obstructed_cache;
6499
6500 if( delta == point_north_west ) {
6501 return cache[from.x][from.y].nw;
6502 }
6503
6504 if( delta == point_north_east ) {
6505 return cache[from.x][from.y].ne;
6506 }
6507
6508 if( delta == point_south_west ) {
6509 return cache[to.x][to.y].ne;
6510 }
6511 if( delta == point_south_east ) {
6512 return cache[to.x][to.y].nw;
6513 }
6514
6515 return false;
6516}
diagonal_blocks vehicle_obstructed_cache[MAPSIZE_X][MAPSIZE_Y]
Definition: map.h:339

References get_cache(), inbounds(), diagonal_blocks::nw, obstructed_by_vehicle_rotation(), point_north_east, point_north_west, point_south_east, point_south_west, level_cache::vehicle_obstructed_cache, tripoint::x, tripoint::xy(), tripoint::y, and tripoint::z.

Referenced by add_splatter_trail(), mattack::boomer(), mattack::boomer_glow(), leap_actor::call(), monster::can_squeeze_to(), choose_adjacent_highlight(), clear_path(), clear_shot_reach(), explosion_handler::do_blast(), mattack::flame(), game::fling_creature(), gas_can_spread_to(), handle_action_menu(), game::knockback(), mattack::longswipe(), avatar_action::move(), npc::move_to(), obstructed_by_vehicle_rotation(), game::peek(), npc::pick_up_item(), process_fields_in_submap(), projectile_attack(), propagate_field(), mattack::ranged_pull(), player::reach_attack(), route_adjacent(), area_expander::run(), scatter_chunks(), and sinkhole_safety_roll().

◆ on_vehicle_moved()

void map::on_vehicle_moved ( int  smz)

Callback invoked when a vehicle has moved.

Definition at line 405 of file map.cpp.

406{
410 set_floor_cache_dirty( smz + 1 );
412}

References set_floor_cache_dirty(), set_outside_cache_dirty(), set_pathfinding_cache_dirty(), and set_transparency_cache_dirty().

Referenced by vehicle::act_on_map(), and displace_vehicle().

◆ open_door()

bool map::open_door ( const tripoint p,
bool  inside,
bool  check_only = false 
)

Definition at line 3869 of file map.cpp.

3870{
3871 const auto &ter = this->ter( p ).obj();
3872 const auto &furn = this->furn( p ).obj();
3873 if( ter.open ) {
3874 if( has_flag( "OPENCLOSE_INSIDE", p ) && !inside ) {
3875 return false;
3876 }
3877
3878 if( !check_only ) {
3879 sounds::sound( p, 6, sounds::sound_t::movement, _( "swish" ), true,
3880 "open_door", ter.id.str() );
3881 ter_set( p, ter.open );
3882
3883 if( ( g->u.has_trait( trait_id( "SCHIZOPHRENIC" ) ) || g->u.has_artifact_with( AEP_SCHIZO ) )
3884 && one_in( 50 ) && !ter.has_flag( "TRANSPARENT" ) ) {
3885 tripoint mp = p + -2 * g->u.pos().xy() + tripoint( 2 * p.x, 2 * p.y, p.z );
3886 g->spawn_hallucination( mp );
3887 }
3888 }
3889
3890 return true;
3891 } else if( furn.open ) {
3892 if( has_flag( "OPENCLOSE_INSIDE", p ) && !inside ) {
3893 return false;
3894 }
3895
3896 if( !check_only ) {
3897 sounds::sound( p, 6, sounds::sound_t::movement, _( "swish" ), true,
3898 "open_door", furn.id.str() );
3899 furn_set( p, furn.open );
3900 }
3901
3902 return true;
3903 } else if( const optional_vpart_position vp = veh_at( p ) ) {
3904 int openable = vp->vehicle().next_part_to_open( vp->part_index(), true );
3905 if( openable >= 0 ) {
3906 if( !check_only ) {
3907 if( !vp->vehicle().handle_potential_theft( dynamic_cast<player &>( g->u ) ) ) {
3908 return false;
3909 }
3910 vp->vehicle().open_all_at( openable );
3911 }
3912
3913 return true;
3914 }
3915
3916 return false;
3917 }
3918
3919 return false;
3920}
@ AEP_SCHIZO
Definition: enums.h:128

References _, AEP_SCHIZO, furn(), furn_set(), g, has_flag(), int_id< T >::id(), sounds::movement, int_id< T >::obj(), one_in(), sounds::sound(), string_id< T >::str(), ter(), ter_set(), veh_at(), tripoint::x, tripoint::y, and tripoint::z.

Referenced by can_interact_at(), npc::can_open_door(), iexamine::door_peephole(), monster::move(), avatar_action::move(), npc::move_to(), open(), and rate_location().

◆ operator=() [1/2]

map & map::operator= ( const map )
delete

◆ operator=() [2/2]

map & map::operator= ( map &&  )
default

◆ partial_con_at()

partial_con * map::partial_con_at ( const tripoint p)

Definition at line 5141 of file map.cpp.

5142{
5143 if( !inbounds( p ) ) {
5144 return nullptr;
5145 }
5146 point l;
5147 submap *const current_submap = get_submap_at( p, l );
5148 auto it = current_submap->partial_constructions.find( tripoint( l, p.z ) );
5149 if( it != current_submap->partial_constructions.end() ) {
5150 return &it->second;
5151 }
5152 return nullptr;
5153}
std::map< tripoint, partial_con > partial_constructions
Definition: submap.h:248

References get_submap_at(), inbounds(), submap::partial_constructions, and tripoint::z.

Referenced by activity_handlers::build_do_turn(), can_do_activity_there(), complete_construction(), generic_multi_activity_check_requirement(), generic_multi_activity_do(), generic_multi_activity_locations(), player_activity::get_progress_message(), place_construction(), game::print_trap_info(), and iexamine::trap().

◆ partial_con_remove()

void map::partial_con_remove ( const tripoint p)

Definition at line 5155 of file map.cpp.

5156{
5157 if( !inbounds( p ) ) {
5158 return;
5159 }
5160 point l;
5161 submap *const current_submap = get_submap_at( p, l );
5162 current_submap->partial_constructions.erase( tripoint( l, p.z ) );
5163}

References get_submap_at(), inbounds(), submap::partial_constructions, and tripoint::z.

Referenced by complete_construction(), and iexamine::trap().

◆ partial_con_set()

void map::partial_con_set ( const tripoint p,
const partial_con con 
)

Definition at line 5165 of file map.cpp.

5166{
5167 if( !inbounds( p ) ) {
5168 return;
5169 }
5170 point l;
5171 submap *const current_submap = get_submap_at( p, l );
5172 if( !current_submap->partial_constructions.emplace( tripoint( l, p.z ), con ).second ) {
5173 debugmsg( "set partial con on top of terrain which already has a partial con" );
5174 }
5175}

References debugmsg, get_submap_at(), inbounds(), submap::partial_constructions, and tripoint::z.

Referenced by construction_activity(), and place_construction().

◆ passable() [1/2]

bool map::passable ( const point p) const
inline

Definition at line 636 of file map.h.

636 {
637 return passable( tripoint( p, abs_sub.z ) );
638 }

References abs_sub, passable(), and tripoint::z.

◆ passable() [2/2]

◆ passable_ter_furn()

bool map::passable_ter_furn ( const tripoint p) const

Definition at line 1833 of file map.cpp.

1834{
1835 return move_cost_ter_furn( p ) != 0;
1836}

References move_cost_ter_furn().

Referenced by impassable_ter_furn(), and avatar_action::move().

◆ pl_line_of_sight()

bool map::pl_line_of_sight ( const tripoint t,
int  max_range 
) const

Uses the map cache to tell if the player could see the given square.

pl_sees implies pl_line_of_sight Used for infrared.

Definition at line 766 of file lightmap.cpp.

767{
768 if( !inbounds( t ) ) {
769 return false;
770 }
771
772 if( max_range >= 0 && square_dist( t, g->u.pos() ) > max_range ) {
773 // Out of range!
774 return false;
775 }
776
777 const auto &map_cache = get_cache_ref( t.z );
778 // Any epsilon > 0 is fine - it means lightmap processing visited the point
779 return map_cache.seen_cache[t.x][t.y] > 0.0f ||
780 map_cache.camera_cache[t.x][t.y] > 0.0f;
781}

References g, get_cache_ref(), inbounds(), square_dist(), tripoint::x, tripoint::y, and tripoint::z.

Referenced by get_heat_radiation(), and Character::sees_with_infrared().

◆ pl_sees()

bool map::pl_sees ( const tripoint t,
int  max_range 
) const

Whether the player character (g->u) can see the given square (local map coordinates).

This only checks the transparency of the path to the target, the light level is not checked.

Parameters
tTarget point to look at
max_rangeAll squares that are further away than this are invisible. Ignored if smaller than 0.

Definition at line 748 of file lightmap.cpp.

749{
750 if( !inbounds( t ) ) {
751 return false;
752 }
753
754 if( max_range >= 0 && square_dist( t, g->u.pos() ) > max_range ) {
755 return false; // Out of range!
756 }
757
758 const auto &map_cache = get_cache_ref( t.z );
759 const apparent_light_info a = apparent_light_helper( map_cache, t );
760 const float light_at_player = map_cache.lm[g->u.posx()][g->u.posy()].max();
761 return !a.obstructed &&
762 ( a.apparent_light >= g->u.get_vision_threshold( light_at_player ) ||
763 map_cache.sm[t.x][t.y] > 0.0 );
764}

References a, apparent_light_helper(), g, get_cache_ref(), inbounds(), square_dist(), tripoint::x, tripoint::y, and tripoint::z.

Referenced by computer_session::action_irradiator(), sounds::process_sound_markers(), and Character::sees().

◆ place_gas_pump() [1/2]

void map::place_gas_pump ( const point p,
int  charges 
)

Definition at line 5451 of file mapgen.cpp.

5452{
5453 place_gas_pump( p, charges, one_in( 4 ) ? "diesel" : "gasoline" );
5454}
void place_gas_pump(const point &p, int charges, const std::string &fuel_type)
Definition: mapgen.cpp:5443

References one_in(), and place_gas_pump().

◆ place_gas_pump() [2/2]

void map::place_gas_pump ( const point p,
int  charges,
const std::string &  fuel_type 
)

Definition at line 5443 of file mapgen.cpp.

5444{
5445 item fuel( fuel_type, calendar::start_of_cataclysm );
5446 fuel.charges = charges;
5447 add_item( p, fuel );
5448 ter_set( p, ter_id( fuel.fuel_pump_terrain() ) );
5449}

References add_item(), item::charges, item::fuel_pump_terrain(), calendar::start_of_cataclysm, ter_id, and ter_set().

Referenced by jmapgen_gaspump::apply(), mapgen_tutorial(), and place_gas_pump().

◆ place_items() [1/2]

std::vector< item * > map::place_items ( const item_group_id loc,
int  chance,
const point p1,
const point p2,
bool  ongrass,
const time_point turn,
int  magazine = 0,
int  ammo = 0 
)
inline

Definition at line 1368 of file map.h.

1370 {
1371 return place_items( loc, chance, tripoint( p1, abs_sub.z ), tripoint( p2, abs_sub.z ), ongrass,
1372 turn, magazine, ammo );
1373 }

References abs_sub, place_items(), calendar::turn, and tripoint::z.

◆ place_items() [2/2]

std::vector< item * > map::place_items ( const item_group_id loc,
int  chance,
const tripoint p1,
const tripoint p2,
bool  ongrass,
const time_point turn,
int  magazine = 0,
int  ammo = 0 
)

Place items from item group in the rectangle f - t.

Several items may be spawned on different places. Several items may spawn at once (at one place) when the item group says so (uses item_group::items_from which may return several items at once).

Parameters
locCurrent location of items to be placed
chanceChance for more items. A chance of 100 creates 1 item all the time, otherwise it's the chance that more items will be created (place items until the random roll with that chance fails). The chance is used for the first item as well, so it may not spawn an item at all. Values <= 0 or > 100 are invalid.
p1One corner of rectangle in which to spawn items
p2Second corner of rectangle in which to spawn items
ongrassIf false the items won't spawn on flat terrain (grass, floor, ...).
turnThe birthday that the created items shall have.
magazinepercentage chance item will contain the default magazine
ammopercentage chance item will be filled with default ammo
Returns
vector containing all placed items

Definition at line 5517 of file mapgen.cpp.

5521{
5522 // TODO: implement for 3D
5523 std::vector<item *> res;
5524
5525 if( chance > 100 || chance <= 0 ) {
5526 debugmsg( "map::place_items() called with an invalid chance (%d)", chance );
5527 return res;
5528 }
5529 if( !item_group::group_is_defined( loc ) ) {
5530 // TODO: fix point types
5532 const oter_id &oid = overmap_buffer.ter( omt );
5533 debugmsg( "place_items: invalid item group '%s', om_terrain = '%s' (%s)",
5534 loc.c_str(), oid.id().c_str(), oid->get_mapgen_id().c_str() );
5535 return res;
5536 }
5537
5538 const float spawn_rate = get_option<float>( "ITEM_SPAWNRATE" );
5539 int spawn_count = roll_remainder( chance * spawn_rate / 100.0f );
5540 for( int i = 0; i < spawn_count; i++ ) {
5541 // Might contain one item or several that belong together like guns & their ammo
5542 int tries = 0;
5543 auto is_valid_terrain = [this, ongrass]( const point & p ) {
5544 auto &terrain = ter( p ).obj();
5545 return terrain.movecost == 0 &&
5546 !terrain.has_flag( "PLACE_ITEM" ) &&
5547 !ongrass &&
5548 !terrain.has_flag( "FLAT" );
5549 };
5550
5551 point p;
5552 do {
5553 p.x = rng( p1.x, p2.x );
5554 p.y = rng( p1.y, p2.y );
5555 tries++;
5556 } while( is_valid_terrain( p ) && tries < 20 );
5557 if( tries < 20 ) {
5558 auto put = put_items_from_loc( loc, tripoint( p, abs_sub.z ), turn );
5559 res.insert( res.end(), put.begin(), put.end() );
5560 }
5561 }
5562 for( auto e : res ) {
5563 if( e->is_tool() || e->is_gun() || e->is_magazine() ) {
5564 if( rng( 0, 99 ) < magazine && !e->magazine_integral() && !e->magazine_current() ) {
5565 e->put_in( item( e->magazine_default(), e->birthday() ) );
5566 }
5567 if( rng( 0, 99 ) < ammo && e->ammo_remaining() == 0 ) {
5568 e->ammo_set( e->ammo_default(), e->ammo_capacity() );
5569 }
5570 }
5571 }
5572 return res;
5573}
constexpr scale omt
Definition: coordinates.h:32
bool group_is_defined(const item_group_id &group_id)
Check whether an item group of the given id exists.
Definition: item_group.cpp:603

References abs_sub, string_id< T >::c_str(), debugmsg, get_abs_sub(), oter_t::get_mapgen_id(), item_group::group_is_defined(), int_id< T >::id(), int_id< T >::obj(), coords::omt, overmap_buffer, put_items_from_loc(), rng(), roll_remainder(), sm_to_omt_copy(), ter(), overmapbuffer::ter(), terrain, calendar::turn, point::x, tripoint::x, point::y, tripoint::y, and tripoint::z.

Referenced by jmapgen_item_group::apply(), draw_lab(), draw_mine(), draw_office_tower(), draw_slimepit(), mapgen_ants_food(), mapgen_ants_generic(), mapgen_ants_larvae(), mapgen_ants_queen(), mapgen_cavern(), mapgen_crater(), mapgen_field(), mapgen_forest(), mapgen_forest_trail_curved(), mapgen_forest_trail_four_way(), mapgen_forest_trail_straight(), mapgen_forest_trail_tee(), mapgen_highway(), mapgen_hive(), mapgen_parking_lot(), mapgen_road(), mapgen_sewer_curved(), mapgen_sewer_four_way(), mapgen_sewer_straight(), mapgen_sewer_tee(), MapExtras::mx_collegekids(), MapExtras::mx_drugdeal(), MapExtras::mx_house_spider(), MapExtras::mx_house_wasp(), MapExtras::mx_military(), MapExtras::mx_minefield(), MapExtras::mx_roadblock(), MapExtras::mx_roadworks(), MapExtras::mx_science(), MapExtras::mx_supplydrop(), place_items(), place_vending(), mission_start::ranch_nurse_8(), mission_start::ranch_scavenger_1(), mission_start::ranch_scavenger_2(), mission_start::ranch_scavenger_3(), and science_room().

◆ place_npc()

character_id map::place_npc ( const point p,
const string_id< npc_template > &  type,
bool  force = false 
)

Definition at line 5484 of file mapgen.cpp.

5485{
5486 if( !force && !get_option<bool>( "STATIC_NPC" ) ) {
5487 return character_id(); //Do not generate an npc.
5488 }
5489 shared_ptr_fast<npc> temp = make_shared_fast<npc>();
5490 temp->normalize();
5491 temp->load_npc_template( type );
5492 temp->spawn_at_precise( { abs_sub.xy() }, { p, abs_sub.z } );
5493 temp->toggle_trait( trait_NPC_STATIC_NPC );
5494 overmap_buffer.insert_npc( temp );
5495 return temp->getID();
5496}
void insert_npc(const shared_ptr_fast< npc > &who)
Adds the npc to an overmap ( based on the npcs current location ) and stores it there.
static const trait_id trait_NPC_STATIC_NPC("NPC_STATIC_NPC")
std::shared_ptr< T > shared_ptr_fast
Definition: memory_fast.h:16

References abs_sub, character_id, overmapbuffer::insert_npc(), overmap_buffer, trait_NPC_STATIC_NPC, type, tripoint::xy(), and tripoint::z.

Referenced by jmapgen_npc::apply(), mapgen_hive(), MapExtras::mx_bandits_block(), MapExtras::mx_looters(), MapExtras::mx_marloss_pilgrimage(), mission_start::ranch_nurse_9(), and place_npc_iuse::use().

◆ place_spawns()

void map::place_spawns ( const mongroup_id group,
int  chance,
const point p1,
const point p2,
float  density,
bool  individual = false,
bool  friendly = false,
const std::string &  name = "NONE",
int  mission_id = -1 
)

Definition at line 5393 of file mapgen.cpp.

5396{
5397 if( !group.is_valid() ) {
5398 // TODO: fix point types
5400 const oter_id &oid = overmap_buffer.ter( omt );
5401 debugmsg( "place_spawns: invalid mongroup '%s', om_terrain = '%s' (%s)", group.c_str(),
5402 oid.id().c_str(), oid->get_mapgen_id().c_str() );
5403 return;
5404 }
5405
5406 // Set chance to be 1 or less to guarantee spawn, else set higher than 1
5407 if( !one_in( chance ) ) {
5408 return;
5409 }
5410
5411 float spawn_density = 1.0f;
5413 spawn_density = get_option< float >( "SPAWN_ANIMAL_DENSITY" );
5414 } else {
5415 spawn_density = get_option< float >( "SPAWN_DENSITY" );
5416 }
5417
5418 float multiplier = density * spawn_density;
5419 // Only spawn 1 creature if individual flag set, else scale by density
5420 float thenum = individual ? 1 : ( multiplier * rng_float( 10.0f, 50.0f ) );
5421 int num = roll_remainder( thenum );
5422
5423 // GetResultFromGroup decrements num
5424 while( num > 0 ) {
5425 int tries = 10;
5426 point p;
5427
5428 // Pick a spot for the spawn
5429 do {
5430 p.x = rng( p1.x, p2.x );
5431 p.y = rng( p1.y, p2.y );
5432 tries--;
5433 } while( impassable( p ) && tries > 0 );
5434
5435 // Pick a monster type
5437
5438 add_spawn( spawn_details.name, spawn_details.pack_size, { p, abs_sub.z },
5439 friendly, -1, mission_id, name );
5440 }
5441}
group
Definition: sounds.h:125

References add_spawn(), string_id< T >::c_str(), debugmsg, friendly, get_abs_sub(), oter_t::get_mapgen_id(), MonsterGroupManager::GetResultFromGroup(), int_id< T >::id(), impassable(), MonsterGroupManager::is_animal(), name(), MonsterGroupResult::name, num, coords::omt, one_in(), overmap_buffer, MonsterGroupResult::pack_size, rng(), rng_float(), roll_remainder(), sm_to_omt_copy(), overmapbuffer::ter(), point::x, and point::y.

Referenced by add_monsters(), jmapgen_monster_group::apply(), create_anomaly(), draw_lab(), draw_mine(), draw_office_tower(), draw_slimepit(), draw_temple(), draw_triffid(), mapgen_road(), MapExtras::mx_collegekids(), MapExtras::mx_corpses(), MapExtras::mx_drugdeal(), MapExtras::mx_military(), MapExtras::mx_pond(), MapExtras::mx_portal(), MapExtras::mx_portal_in(), MapExtras::mx_science(), and science_room().

◆ place_toilet()

void map::place_toilet ( const point p,
int  charges = 6 * 4 
)

Definition at line 5456 of file mapgen.cpp.

5457{
5458 item water( "water", calendar::start_of_cataclysm );
5459 water.charges = charges;
5460 add_item( p, water );
5461 furn_set( p, f_toilet );
5462}

References add_item(), item::charges, f_toilet, furn_set(), and calendar::start_of_cataclysm.

Referenced by jmapgen_toilet::apply(), and mapf::formatted_set_simple().

◆ place_vending()

void map::place_vending ( const point p,
const item_group_id type,
bool  reinforced = false 
)

Definition at line 5464 of file mapgen.cpp.

5465{
5466 if( reinforced ) {
5468 place_items( type, 100, p, p, false, calendar::start_of_cataclysm );
5469 } else {
5470 if( one_in( 2 ) ) {
5471 furn_set( p, f_vending_o );
5472 for( const auto &loc : points_in_radius( { p, abs_sub.z }, 1 ) ) {
5473 if( one_in( 4 ) ) {
5474 spawn_item( loc, "glass_shard", rng( 1, 2 ) );
5475 }
5476 }
5477 } else {
5478 furn_set( p, f_vending_c );
5479 place_items( type, 100, p, p, false, calendar::start_of_cataclysm );
5480 }
5481 }
5482}
furn_id f_vending_o
Definition: mapdata.cpp:1109
furn_id f_vending_reinforced
Definition: mapdata.cpp:1132
furn_id f_vending_c
Definition: mapdata.cpp:1109

References abs_sub, f_vending_c, f_vending_o, f_vending_reinforced, furn_set(), one_in(), place_items(), points_in_radius(), rng(), spawn_item(), calendar::start_of_cataclysm, type, and tripoint::z.

Referenced by jmapgen_vending_machine::apply().

◆ player_in_field()

void map::player_in_field ( player u)
protected

Definition at line 1224 of file map_field.cpp.

1225{
1226 // A copy of the current field for reference. Do not add fields to it, use map::add_field
1227 field &curfield = get_field( u.pos() );
1228 // Are we inside?
1229 bool inside = false;
1230 // If we are in a vehicle figure out if we are inside (reduces effects usually)
1231 // and what part of the vehicle we need to deal with.
1232 if( u.in_vehicle ) {
1233 if( const optional_vpart_position vp = veh_at( u.pos() ) ) {
1234 inside = vp->is_inside();
1235 }
1236 }
1237
1238 // Iterate through all field effects on this tile.
1239 // Do not remove the field with remove_field, instead set it's intensity to 0. It will be removed
1240 // later by the field processing, which will also adjust field_count accordingly.
1241 for( auto &field_list_it : curfield ) {
1242 field_entry &cur = field_list_it.second;
1243 if( !cur.is_field_alive() ) {
1244 continue;
1245 }
1246
1247 // Do things based on what field effect we are currently in.
1248 const field_type_id ft = cur.get_field_type();
1249 if( ft == fd_web ) {
1250 // If we are in a web, can't walk in webs or are in a vehicle, get webbed maybe.
1251 // Moving through multiple webs stacks the effect.
1252 if( !u.has_trait( trait_WEB_WALKER ) && !u.in_vehicle ) {
1253 // Between 5 and 15 minus your current web level.
1254 u.add_effect( effect_webbed, 1_turns, num_bp, cur.get_field_intensity() );
1255 // It is spent.
1256 cur.set_field_intensity( 0 );
1257 continue;
1258 // If you are in a vehicle destroy the web.
1259 // It should of been destroyed when you ran over it anyway.
1260 } else if( u.in_vehicle ) {
1261 cur.set_field_intensity( 0 );
1262 continue;
1263 }
1264 }
1265 if( ft == fd_acid ) {
1266 // Assume vehicles block acid damage entirely,
1267 // you're certainly not standing in it.
1268 if( !u.in_vehicle && !u.has_trait( trait_ACIDPROOF ) ) {
1269 int total_damage = 0;
1270 total_damage += burn_body_part( u, cur, bp_foot_l, 2 );
1271 total_damage += burn_body_part( u, cur, bp_foot_r, 2 );
1272 const bool on_ground = u.is_on_ground();
1273 if( on_ground ) {
1274 // Apply the effect to the remaining body parts
1275 total_damage += burn_body_part( u, cur, bp_leg_l, 2 );
1276 total_damage += burn_body_part( u, cur, bp_leg_r, 2 );
1277 total_damage += burn_body_part( u, cur, bp_hand_l, 2 );
1278 total_damage += burn_body_part( u, cur, bp_hand_r, 2 );
1279 total_damage += burn_body_part( u, cur, bp_torso, 2 );
1280 // Less arms = less ability to keep upright
1281 if( ( !u.has_two_arms() && one_in( 4 ) ) || one_in( 2 ) ) {
1282 total_damage += burn_body_part( u, cur, bp_arm_l, 1 );
1283 total_damage += burn_body_part( u, cur, bp_arm_r, 1 );
1284 total_damage += burn_body_part( u, cur, bp_head, 1 );
1285 }
1286 }
1287
1288 if( on_ground && total_damage > 0 ) {
1289 u.add_msg_player_or_npc( m_bad, _( "The acid burns your body!" ),
1290 _( "The acid burns <npcname>s body!" ) );
1291 } else if( total_damage > 0 ) {
1292 u.add_msg_player_or_npc( m_bad, _( "The acid burns your legs and feet!" ),
1293 _( "The acid burns <npcname>s legs and feet!" ) );
1294 } else if( on_ground ) {
1295 u.add_msg_if_player( m_warning, _( "You're lying in a pool of acid" ) );
1296 } else {
1297 u.add_msg_if_player( m_warning, _( "You're standing in a pool of acid" ) );
1298 }
1299
1300 u.check_dead_state();
1301 }
1302 }
1303 if( ft == fd_sap ) {
1304 // Sap does nothing to cars.
1305 if( !u.in_vehicle ) {
1306 // Use up sap.
1308 }
1309 }
1310 if( ft == fd_sludge ) {
1311 // Sludge is on the ground, but you are above the ground when boarded on a vehicle
1312 if( !u.in_vehicle ) {
1313 u.add_msg_if_player( m_bad, _( "The sludge is thick and sticky. You struggle to pull free." ) );
1314 u.moves -= cur.get_field_intensity() * 300;
1315 cur.set_field_intensity( 0 );
1316 }
1317 }
1318 if( ft == fd_fire ) {
1319 // Heatsink or suit prevents ALL fire damage.
1321
1322 // To modify power of a field based on... whatever is relevant for the effect.
1323 int adjusted_intensity = cur.get_field_intensity();
1324 // Burn the player. Less so if you are in a car or ON a car.
1325 if( u.in_vehicle ) {
1326 if( inside ) {
1327 adjusted_intensity -= 2;
1328 } else {
1329 adjusted_intensity -= 1;
1330 }
1331 }
1332
1333 if( adjusted_intensity >= 1 ) {
1334 // Burn message by intensity
1335 static const std::array<std::string, 4> player_burn_msg = { {
1336 translate_marker( "You burn your legs and feet!" ),
1337 translate_marker( "You're burning up!" ),
1338 translate_marker( "You're set ablaze!" ),
1339 translate_marker( "Your whole body is burning!" )
1340 }
1341 };
1342 static const std::array<std::string, 4> npc_burn_msg = { {
1343 translate_marker( "<npcname> burns their legs and feet!" ),
1344 translate_marker( "<npcname> is burning up!" ),
1345 translate_marker( "<npcname> is set ablaze!" ),
1346 translate_marker( "<npcname>s whole body is burning!" )
1347 }
1348 };
1349 static const std::array<std::string, 4> player_warn_msg = { {
1350 translate_marker( "You're standing in a fire!" ),
1351 translate_marker( "You're waist-deep in a fire!" ),
1352 translate_marker( "You're surrounded by raging fire!" ),
1353 translate_marker( "You're lying in fire!" )
1354 }
1355 };
1356
1357 const int burn_min = adjusted_intensity;
1358 const int burn_max = 3 * adjusted_intensity + 3;
1359 std::list<bodypart_id> parts_burned;
1360 int msg_num = adjusted_intensity - 1;
1361 if( !u.is_on_ground() ) {
1362 switch( adjusted_intensity ) {
1363 case 3:
1364 parts_burned.push_back( bodypart_id( "hand_l" ) );
1365 parts_burned.push_back( bodypart_id( "hand_r" ) );
1366 parts_burned.push_back( bodypart_id( "arm_l" ) );
1367 parts_burned.push_back( bodypart_id( "arm_r" ) );
1368 /* fallthrough */
1369 case 2:
1370 parts_burned.push_back( bodypart_id( "torso" ) );
1371 /* fallthrough */
1372 case 1:
1373 parts_burned.push_back( bodypart_id( "foot_l" ) );
1374 parts_burned.push_back( bodypart_id( "foot_r" ) );
1375 parts_burned.push_back( bodypart_id( "leg_l" ) );
1376 parts_burned.push_back( bodypart_id( "leg_r" ) );
1377 }
1378 } else {
1379 // Lying in the fire is BAAAD news, hits every body part.
1380 msg_num = 3;
1381 const std::vector<bodypart_id> &all_parts = u.get_all_body_parts();
1382 // HACK: Skip num_bp part
1383 for( auto bp : all_parts ) {
1384 if( bp->token != num_bp ) {
1385 parts_burned.push_back( bp );
1386 }
1387 }
1388 }
1389
1390 int total_damage = 0;
1391 for( const bodypart_id part_burned : parts_burned ) {
1392 const dealt_damage_instance dealt = u.deal_damage( nullptr, part_burned,
1393 damage_instance( DT_HEAT, rng( burn_min, burn_max ) ) );
1394 total_damage += dealt.type_damage( DT_HEAT );
1395 }
1396 if( total_damage > 0 ) {
1397 u.add_msg_player_or_npc( m_bad, _( player_burn_msg[msg_num] ), _( npc_burn_msg[msg_num] ) );
1398 } else {
1399 u.add_msg_if_player( m_warning, _( player_warn_msg[msg_num] ) );
1400 }
1401 u.check_dead_state();
1402 }
1403 }
1404
1405 }
1406 if( ft == fd_tear_gas ) {
1407 // Tear gas will both give you teargas disease and/or blind you.
1408 if( ( cur.get_field_intensity() > 1 || !one_in( 3 ) ) && ( !inside || one_in( 3 ) ) ) {
1409 u.add_env_effect( effect_teargas, bp_mouth, 5, 20_seconds );
1410 }
1411 if( cur.get_field_intensity() > 1 && ( !inside || one_in( 3 ) ) ) {
1412 u.add_env_effect( effect_blind, bp_eyes, cur.get_field_intensity() * 2, 10_seconds );
1413 }
1414 }
1415 if( ft == fd_fungal_haze ) {
1416 if( !u.has_trait( trait_M_IMMUNE ) && ( !inside || one_in( 4 ) ) ) {
1417 u.add_env_effect( effect_fungus, bp_mouth, 4, 10_minutes, num_bp );
1418 u.add_env_effect( effect_fungus, bp_eyes, 4, 10_minutes, num_bp );
1419 }
1420 }
1421 if( ft == fd_dazzling ) {
1422 if( cur.get_field_intensity() > 1 || one_in( 5 ) ) {
1423 u.add_env_effect( effect_blind, bp_eyes, 10, 10_turns );
1424 } else {
1425 u.add_env_effect( effect_blind, bp_eyes, 2, 2_turns );
1426 }
1427 }
1428
1429 if( cur.extra_radiation_min() > 0 ) {
1430 // Get irradiated by the nuclear fallout.
1431 const float rads = rng( cur.extra_radiation_min() + 1,
1432 cur.extra_radiation_max() * ( cur.extra_radiation_max() + 1 ) );
1433 const bool rad_proof = !u.irradiate( rads );
1434 // TODO: Reduce damage for rad resistant?
1435 if( cur.radiation_hurt_damage_min() > 0 && !rad_proof ) {
1437 u.hurtall( rng( cur.radiation_hurt_damage_min(), cur.radiation_hurt_damage_max() ), nullptr );
1438 }
1439 }
1440 if( ft == fd_flame_burst ) {
1441 // A burst of flame? Only hits the legs and torso.
1442 if( !inside ) {
1443 // Fireballs can't touch you inside a car.
1444 // Heatsink or suit stops fire.
1445 if( !u.has_active_bionic( bio_heatsink ) &&
1447 u.add_msg_player_or_npc( m_bad, _( "You're torched by flames!" ),
1448 _( "<npcname> is torched by flames!" ) );
1449 u.deal_damage( nullptr, bodypart_id( "leg_l" ), damage_instance( DT_HEAT, rng( 2, 6 ) ) );
1450 u.deal_damage( nullptr, bodypart_id( "leg_r" ), damage_instance( DT_HEAT, rng( 2, 6 ) ) );
1451 u.deal_damage( nullptr, bodypart_id( "torso" ), damage_instance( DT_HEAT, rng( 4, 9 ) ) );
1452 u.check_dead_state();
1453 } else {
1454 u.add_msg_player_or_npc( _( "These flames do not burn you." ),
1455 _( "Those flames do not burn <npcname>." ) );
1456 }
1457 }
1458 }
1459 if( ft == fd_electricity ) {
1460 // Small universal damage based on intensity, only if not electroproofed.
1461 if( !u.is_elec_immune() ) {
1462 int total_damage = 0;
1463 for( size_t i = 0; i < num_hp_parts; i++ ) {
1464 const bodypart_id bp = convert_bp( player::hp_to_bp( static_cast<hp_part>( i ) ) ).id();
1465 const int dmg = rng( 1, cur.get_field_intensity() );
1466 total_damage += u.deal_damage( nullptr, bp, damage_instance( DT_ELECTRIC, dmg ) ).total_damage();
1467 }
1468
1469 if( total_damage > 0 ) {
1471 u.add_msg_player_or_npc( m_bad, _( "You're painfully electrocuted!" ),
1472 _( "<npcname> is shocked!" ) );
1473 u.mod_pain( total_damage / 2 );
1474 } else {
1475 u.add_msg_player_or_npc( m_bad, _( "You're shocked!" ), _( "<npcname> is shocked!" ) );
1476 }
1477 } else {
1478 u.add_msg_player_or_npc( _( "The electric cloud doesn't affect you." ),
1479 _( "The electric cloud doesn't seem to affect <npcname>." ) );
1480 }
1481 }
1482 }
1483 if( ft == fd_fatigue ) {
1484 // Assume the rift is on the ground for now to prevent issues with the player being unable access vehicle controls on the same tile due to teleportation.
1485 if( !u.in_vehicle ) {
1486 // Teleports you... somewhere.
1487 if( rng( 0, 2 ) < cur.get_field_intensity() && u.is_player() ) {
1488 add_msg( m_bad, _( "You're violently teleported!" ) );
1489 u.hurtall( cur.get_field_intensity(), nullptr );
1490 teleport::teleport( u );
1491 }
1492 }
1493 }
1494 // Why do these get removed???
1495 // Stepping on a shock vent shuts it down.
1496 if( ft == fd_shock_vent || ft == fd_acid_vent ) {
1497 cur.set_field_intensity( 0 );
1498 }
1499 if( ft == fd_bees ) {
1500 // Player is immune to bees while underwater.
1501 if( !u.is_underwater() ) {
1502 const int intensity = cur.get_field_intensity();
1503 // Bees will try to sting you in random body parts, up to 8 times.
1504 for( int i = 0; i < rng( 1, 7 ); i++ ) {
1506 int sum_cover = 0;
1507 for( const item &i : u.worn ) {
1508 if( i.covers( bp->token ) ) {
1509 sum_cover += i.get_coverage();
1510 }
1511 }
1512 // Get stung if [clothing on a body part isn't thick enough (like t-shirt) OR clothing covers less than 100% of body part]
1513 // AND clothing on affected body part has low environmental protection value
1514 if( ( u.get_armor_cut( bp ) <= 1 || ( sum_cover < 100 && x_in_y( 100 - sum_cover, 100 ) ) ) &&
1515 u.add_env_effect( effect_stung, bp->token, intensity, 9_minutes ) ) {
1516 u.add_msg_if_player( m_bad, _( "The bees sting you in %s!" ),
1517 body_part_name_accusative( bp->token ) );
1518 }
1519 }
1520 }
1521 }
1522 if( ft == fd_incendiary ) {
1523 // Mysterious incendiary substance melts you horribly.
1524 if( u.has_trait( trait_M_SKIN2 ) ||
1525 u.has_trait( trait_M_SKIN3 ) ||
1526 cur.get_field_intensity() == 1 ) {
1527 u.add_msg_player_or_npc( m_bad, _( "The incendiary burns you!" ),
1528 _( "The incendiary burns <npcname>!" ) );
1529 u.hurtall( rng( 1, 3 ), nullptr );
1530 } else {
1531 u.add_msg_player_or_npc( m_bad, _( "The incendiary melts into your skin!" ),
1532 _( "The incendiary melts into <npcname>s skin!" ) );
1533 u.add_effect( effect_onfire, 8_turns, bp_torso );
1534 u.hurtall( rng( 2, 6 ), nullptr );
1535 }
1536 }
1537 // Both gases are unhealthy and become deadly if you cross a related threshold.
1538 if( ft == fd_fungicidal_gas || ft == fd_insecticidal_gas ) {
1539 // The gas won't harm you inside a vehicle.
1540 if( !inside ) {
1541 // Full body suits protect you from the effects of the gas.
1542 if( !( u.worn_with_flag( flag_GAS_PROOF ) && u.get_env_resist( bodypart_id( "mouth" ) ) >= 15 &&
1543 u.get_env_resist( bodypart_id( "eyes" ) ) >= 15 ) ) {
1544 const int intensity = cur.get_field_intensity();
1545 bool inhaled = u.add_env_effect( effect_poison, bp_mouth, 5, intensity * 1_minutes );
1547 ( ft == fd_insecticidal_gas && ( u.get_highest_category() == "INSECT" ||
1548 u.get_highest_category() == "SPIDER" ) ) ) {
1549 inhaled |= u.add_env_effect( effect_badpoison, bp_mouth, 5, intensity * 1_minutes );
1550 u.hurtall( rng( intensity, intensity * 2 ), nullptr );
1551 u.add_msg_if_player( m_bad, _( "The %s burns your skin." ), cur.name() );
1552 }
1553
1554 if( inhaled ) {
1555 u.add_msg_if_player( m_bad, _( "The %s makes you feel sick." ), cur.name() );
1556 }
1557 }
1558 }
1559 }
1560 }
1561}
std::string body_part_name_accusative(body_part bp, int number)
Returns the matching accusative name of the body_part token, i.e.
Definition: bodypart.cpp:329
@ bp_foot_l
Definition: bodypart.h:50
@ bp_leg_r
Definition: bodypart.h:49
@ bp_eyes
Definition: bodypart.h:42
@ bp_hand_l
Definition: bodypart.h:46
@ bp_arm_l
Definition: bodypart.h:44
@ bp_leg_l
Definition: bodypart.h:48
@ bp_hand_r
Definition: bodypart.h:47
@ bp_head
Definition: bodypart.h:41
@ bp_torso
Definition: bodypart.h:40
@ bp_mouth
Definition: bodypart.h:43
@ bp_foot_r
Definition: bodypart.h:51
@ bp_arm_r
Definition: bodypart.h:45
bool is_elec_immune() const override
Returns true is the player is protected from electric shocks.
Definition: character.cpp:6191
bool worn_with_flag(const std::string &flag, const bodypart_id &bp=bodypart_str_id::NULL_ID()) const
Returns true if the player is wearing an item with the given flag.
Definition: character.cpp:3270
bool is_on_ground() const override
Returns true if the player is knocked over or has broken legs.
Definition: character.cpp:962
std::list< item > worn
Definition: character.h:1507
int get_env_resist(bodypart_id bp) const override
Returns overall env_resist on a body_part.
Definition: character.cpp:7133
bool has_two_arms() const
Returns true if the player has two functioning arms.
Definition: character.cpp:1280
int get_armor_cut(bodypart_id bp) const override
Returns overall cutting resistance for the body_part.
Definition: character.cpp:6976
std::string get_highest_category() const
Returns the highest mutation category.
Definition: character.cpp:7970
bool is_wearing(const item &itm) const
Returns true if the player is wearing the item.
Definition: character.cpp:3240
void hurtall(int dam, Creature *source, bool disturb=true)
Hurts all body parts for dam, no armor reduction.
Definition: character.cpp:8666
bool has_trait(const trait_id &b) const override
Returns true if the player has the entered trait.
Definition: mutation.cpp:103
bool irradiate(float rads, bool bypass=false)
Handles mitigation and application of radiation.
Definition: suffer.cpp:1531
static body_part hp_to_bp(hp_part hpart)
Converts an hp_part to a body_part.
Definition: character.cpp:6589
bool has_active_bionic(const bionic_id &b) const
Returns true if the player has the entered bionic id and it is powered on.
Definition: character.cpp:1887
bodypart_id get_random_body_part(bool main=false) const
Definition: creature.cpp:1620
virtual bool is_underwater() const
Definition: creature.cpp:174
std::vector< bodypart_id > get_all_body_parts(bool only_main=false) const
Returns body parts this creature have.
Definition: creature.cpp:1627
int extra_radiation_min() const
Definition: field.cpp:14
int radiation_hurt_damage_min() const
Definition: field.cpp:24
std::string radiation_hurt_message() const
Definition: field.cpp:34
int extra_radiation_max() const
Definition: field.cpp:19
std::string name() const
Definition: field.h:84
int radiation_hurt_damage_max() const
Definition: field.cpp:29
int get_coverage() const
Returns the relative coverage that this item has when worn.
Definition: item.cpp:5771
bool covers(body_part bp) const
Whether this item (when worn) covers the given body part.
Definition: item.cpp:743
int burn_body_part(player &u, field_entry &cur, body_part bp, int scale)
Definition: map_field.cpp:124
void mod_pain(int npain) override
Modifies a pain value by player traits before passing it to Creature::mod_pain()
Definition: player.cpp:945
void add_msg_if_player(const std::string &msg) const override
Definition: player.cpp:3973
bool is_player() const override
Definition: player.h:106
field_type_id fd_bees
Definition: field_type.cpp:371
static const trait_id trait_M_SKIN3("M_SKIN3")
static const std::string flag_GAS_PROOF("GAS_PROOF")
static const efftype_id effect_fungus("fungus")
static const trait_id trait_ELECTRORECEPTORS("ELECTRORECEPTORS")
static const trait_id trait_THRESH_MARLOSS("THRESH_MARLOSS")
static const trait_id trait_WEB_WALKER("WEB_WALKER")
static const efftype_id effect_badpoison("badpoison")
static const itype_id itype_rm13_armor_on("rm13_armor_on")
static const trait_id trait_M_IMMUNE("M_IMMUNE")
static const trait_id trait_THRESH_MYCUS("THRESH_MYCUS")
static const trait_id trait_ACIDPROOF("ACIDPROOF")
static const trait_id trait_M_SKIN2("M_SKIN2")
static const efftype_id effect_stung("stung")
static const efftype_id effect_poison("poison")
static const efftype_id effect_teargas("teargas")
static const bionic_id bio_heatsink("bio_heatsink")
hp_part
Definition: pldata.h:32
@ num_hp_parts
Definition: pldata.h:39
int type_damage(damage_type dt) const
Definition: damage.cpp:172
#define translate_marker(x)
Marks a string literal to be extracted for translation.
Definition: translations.h:30

References _, Creature::add_effect(), Creature::add_env_effect(), add_msg(), player::add_msg_if_player(), player::add_msg_player_or_npc(), bio_heatsink, body_part_name_accusative(), bp_arm_l, bp_arm_r, bp_eyes, bp_foot_l, bp_foot_r, bp_hand_l, bp_hand_r, bp_head, bp_leg_l, bp_leg_r, bp_mouth, bp_torso, burn_body_part(), Creature::check_dead_state(), convert_bp(), item::covers(), Character::deal_damage(), DT_ELECTRIC, DT_HEAT, effect_badpoison, effect_blind, effect_fungus, effect_onfire, effect_poison, effect_stung, effect_teargas, effect_webbed, field_entry::extra_radiation_max(), field_entry::extra_radiation_min(), fd_acid, fd_acid_vent, fd_bees, fd_dazzling, fd_electricity, fd_fatigue, fd_fire, fd_flame_burst, fd_fungal_haze, fd_fungicidal_gas, fd_incendiary, fd_insecticidal_gas, fd_sap, fd_shock_vent, fd_sludge, fd_tear_gas, fd_web, flag_GAS_PROOF(), Creature::get_all_body_parts(), Character::get_armor_cut(), item::get_coverage(), Character::get_env_resist(), get_field(), field_entry::get_field_intensity(), field_entry::get_field_type(), Character::get_highest_category(), Creature::get_random_body_part(), Character::has_active_bionic(), Character::has_trait(), Character::has_two_arms(), Character::hp_to_bp(), Character::hurtall(), string_id< T >::id(), Character::in_vehicle, Character::irradiate(), Character::is_elec_immune(), field_entry::is_field_alive(), Character::is_on_ground(), player::is_player(), Creature::is_underwater(), Character::is_wearing(), itype_rm13_armor_on, m_bad, m_warning, player::mod_pain(), Creature::moves, field_entry::name(), num_bp, num_hp_parts, one_in(), Character::pos(), field_entry::radiation_hurt_damage_max(), field_entry::radiation_hurt_damage_min(), field_entry::radiation_hurt_message(), rng(), field_entry::set_field_intensity(), teleport::teleport(), dealt_damage_instance::total_damage(), trait_ACIDPROOF, trait_ELECTRORECEPTORS, trait_M_IMMUNE, trait_M_SKIN2, trait_M_SKIN3, trait_THRESH_MARLOSS, trait_THRESH_MYCUS, trait_WEB_WALKER, translate_marker, dealt_damage_instance::type_damage(), veh_at(), Character::worn, Character::worn_with_flag(), and x_in_y().

Referenced by creature_in_field().

◆ point_within_camp()

bool map::point_within_camp ( const tripoint point_check) const

Definition at line 5553 of file map.cpp.

5554{
5555 // TODO: fix point types
5556 const tripoint_abs_omt omt_check( ms_to_omt_copy( point_check ) );
5557 const point_abs_omt p = omt_check.xy();
5558 for( int x2 = -2; x2 < 2; x2++ ) {
5559 for( int y2 = -2; y2 < 2; y2++ ) {
5560 if( cata::optional<basecamp *> bcp = overmap_buffer.find_camp( p + point( x2, y2 ) ) ) {
5561 return ( *bcp )->camp_omt_pos().z() == point_check.z;
5562 }
5563 }
5564 }
5565 return false;
5566}
constexpr auto xy() const
Definition: coordinates.h:130
cata::optional< basecamp * > find_camp(const point_abs_omt &p)

References overmapbuffer::find_camp(), ms_to_omt_copy(), overmap_buffer, coords::coord_point< Point, Origin, Scale >::xy(), and tripoint::z.

Referenced by npc::worker_downtime().

◆ points_in_radius()

tripoint_range< tripoint > map::points_in_radius ( const tripoint center,
size_t  radius,
size_t  radiusz = 0 
) const

Definition at line 8605 of file map.cpp.

8607{
8608 const tripoint min( std::max<int>( 0, center.x - radius ), std::max<int>( 0, center.y - radius ),
8609 clamp<int>( center.z - radiusz, -OVERMAP_DEPTH, OVERMAP_HEIGHT ) );
8610 const tripoint max( std::min<int>( SEEX * my_MAPSIZE - 1, center.x + radius ),
8611 std::min<int>( SEEX * my_MAPSIZE - 1, center.y + radius ), clamp<int>( center.z + radiusz,
8613 return tripoint_range<tripoint>( min, max );
8614}

References center, my_MAPSIZE, OVERMAP_DEPTH, OVERMAP_HEIGHT, and SEEX.

Referenced by computer_session::action_blood_anal(), computer_session::action_conveyor(), computer_session::action_data_anal(), computer_session::action_deactivate_shock_vent(), computer_session::action_extract_rad_source(), computer_session::action_geiger(), computer_session::action_irradiator(), computer_session::action_sample(), Character::activate_bionic(), add_splash(), Character::adjacent_tile(), npc::alt_attack(), are_requirements_nearby(), npc::assess_danger(), bash_furn_success(), Character::blossoms(), build_vision_transparency_cache(), activity_handlers::butcher_finish(), leap_actor::call(), can_do_activity_there(), iexamine::cardreader(), iexamine::cardreader_foodplace(), deploy_tent_actor::check_intact(), choose_adjacent_highlight(), activity_handlers::chop_tree_finish(), climb_difficulty(), collapse_at(), collapse_check(), complete_construction(), consider_butchery(), game::control_vehicle(), displace_water(), enumerate_objects_around_point(), Character::env_surgery_bonus(), ranged::execute_shaped_attack(), ranged::expected_coverage(), computer_session::failure_destroy_blood(), computer_session::failure_destroy_data(), computer_session::failure_manhacks(), computer_session::failure_secubots(), computer_session::failure_shutdown(), find_empty_spot_nearby(), find_furnitures_with_flag_in_radius(), find_potential_computer_point(), hacking_activity_actor::finish(), activity_handlers::forage_finish(), game::forced_door_closing(), basecamp::form_crafting_inventory(), inventory::form_from_map(), generic_multi_activity_check_requirement(), generic_multi_activity_locations(), get_creatures_in_radius(), get_heat_radiation(), liquid_handler::get_liquid_target(), zone_manager::get_point_set_loot(), iexamine::getGasPumpByNumber(), iexamine::getNearFilledGasTank(), getNearPumpCount(), npc::go_to_omt_destination(), handle_action_menu(), has_adjacent_furniture_with(), has_nearby_chair(), has_nearby_fire(), has_nearby_table(), has_neighbor(), is_cornerfloor(), is_wall_adjacent(), map_funcs::migo_nerve_cage_removal(), game::monmove(), npc::move_away_from(), MapExtras::mx_casings(), MapExtras::mx_corpses(), MapExtras::mx_looters(), MapExtras::mx_marloss_pilgrimage(), MapExtras::mx_mayhem(), MapExtras::mx_minefield(), MapExtras::mx_portal(), MapExtras::mx_portal_in(), iexamine::nanofab(), iuse::note_bionics(), trap::on_disarmed(), operator_present(), tutorial_game::per_turn(), photo_def_for_camera_point(), place_construction(), game::place_critter_around(), mission_start::place_deposit_box(), game::place_player(), place_vending(), player_on_couch(), iexamine::portable_structure(), tutorial_game::post_action(), game::process_artifact(), process_fields_in_submap(), propagate_suspension_check(), avatar_action::ramp_move(), reachable_flood_steps(), editmap::recalc_target(), requirements_map(), mattack::riotbot(), route_adjacent(), mattack::shriek_stun(), spawn_monsters_submap(), mdeath::splatter(), Character::spores(), fungal_effects::spread_fungus(), spread_gas(), monster::stumble(), activity_handlers::travel_do_turn(), explosion_iuse::trigger_explosion(), try_remove_grab(), turnOnSelectedPump(), place_trap_actor::use(), deploy_tent_actor::use(), use_amount(), game::vertical_move(), and npc::worker_downtime().

◆ points_in_rectangle()

tripoint_range< tripoint > map::points_in_rectangle ( const tripoint from,
const tripoint to 
) const

Definition at line 8595 of file map.cpp.

8596{
8597 const tripoint min( std::max( 0, std::min( from.x, to.x ) ), std::max( 0, std::min( from.y,
8598 to.y ) ), std::max( -OVERMAP_DEPTH, std::min( from.z, to.z ) ) );
8599 const tripoint max( std::min( SEEX * my_MAPSIZE - 1, std::max( from.x, to.x ) ),
8600 std::min( SEEX * my_MAPSIZE - 1, std::max( from.y, to.y ) ), std::min( OVERMAP_HEIGHT,
8601 std::max( from.z, to.z ) ) );
8602 return tripoint_range<tripoint>( min, max );
8603}

References my_MAPSIZE, OVERMAP_DEPTH, OVERMAP_HEIGHT, SEEX, tripoint::x, tripoint::y, and tripoint::z.

Referenced by apply_camp_ownership(), apply_faction_ownership(), debug_menu::debug(), draw_lab(), farm_action(), game::find_or_make_stairs(), generate_lightmap(), jmapgen_setmap::has_vehicle_collision(), avatar_action::move(), MapExtras::mx_portal(), om_cutdown_trees(), om_harvest_furn(), om_harvest_itm(), and om_harvest_ter().

◆ points_on_zlevel() [1/2]

◆ points_on_zlevel() [2/2]

tripoint_range< tripoint > map::points_on_zlevel ( int  z) const

Same as above, but uses the specific z-level.

If the given z-level is invalid, it returns an empty range.

Definition at line 8616 of file map.cpp.

8617{
8618 if( z < -OVERMAP_DEPTH || z > OVERMAP_HEIGHT ) {
8619 // TODO: need a default constructor that creates an empty range.
8621 }
8623 tripoint( 0, 0, z ), tripoint( SEEX * my_MAPSIZE - 1, SEEY * my_MAPSIZE - 1, z ) );
8624}

References my_MAPSIZE, OVERMAP_HEIGHT, SEEX, SEEY, tripoint_above, and tripoint_zero.

◆ process_falling()

void map::process_falling ( )

Invoked drop_everything on cached dirty tiles.

Definition at line 2274 of file map.cpp.

2275{
2276 if( !zlevels ) {
2277 support_cache_dirty.clear();
2278 return;
2279 }
2280
2281 if( !support_cache_dirty.empty() ) {
2282 add_msg( m_debug, "Checking %d tiles for falling objects",
2283 support_cache_dirty.size() );
2284 // We want the cache to stay constant, but falling can change it
2285 std::set<tripoint> last_cache = std::move( support_cache_dirty );
2286 support_cache_dirty.clear();
2287 for( const tripoint &p : last_cache ) {
2288 drop_everything( p );
2289 }
2290 }
2291}
void drop_everything(const tripoint &p)
Handles map objects of given type (not creatures) falling down.
Definition: map.cpp:2045
std::set< tripoint > support_cache_dirty
Definition: map.h:1553

References add_msg(), drop_everything(), m_debug, avatar_action::move(), support_cache_dirty, and zlevels.

Referenced by game::do_turn().

◆ process_fields()

void map::process_fields ( )

Definition at line 141 of file map_field.cpp.

142{
143 const int minz = zlevels ? -OVERMAP_DEPTH : abs_sub.z;
144 const int maxz = zlevels ? OVERMAP_HEIGHT : abs_sub.z;
145 for( int z = minz; z <= maxz; z++ ) {
146 auto &field_cache = get_cache( z ).field_cache;
147 for( int x = 0; x < my_MAPSIZE; x++ ) {
148 for( int y = 0; y < my_MAPSIZE; y++ ) {
149 if( field_cache[ x + y * MAPSIZE ] ) {
150 submap *const current_submap = get_submap_at_grid( { x, y, z } );
151 process_fields_in_submap( current_submap, tripoint( x, y, z ) );
152 }
153 }
154 }
155
156 // no need to invalidate "transparency" and "seen" caches here
157 // they are invalidated point by point inside the `process_fields_in_submap`
158 }
159}
void process_fields_in_submap(submap *current_submap, const tripoint &submap_pos)
Definition: map_field.cpp:396

References abs_sub, level_cache::field_cache, get_cache(), get_submap_at_grid(), MAPSIZE, my_MAPSIZE, OVERMAP_DEPTH, OVERMAP_HEIGHT, process_fields_in_submap(), tripoint::z, and zlevels.

Referenced by game::do_turn().

◆ process_fields_in_submap()

void map::process_fields_in_submap ( submap current_submap,
const tripoint submap_pos 
)

Definition at line 396 of file map_field.cpp.

398{
399 scent_block sblk( submap, g->scent );
400
401 // Holds m.field_at(x,y).find_field(fd_some_field) type returns.
402 // Just to avoid typing that long string for a temp value.
403 field_entry *tmpfld = nullptr;
404
405 map &here = get_map();
406 tripoint thep;
407 thep.z = submap.z;
408
409 // Initialize the map tile wrapper
410 maptile map_tile( current_submap, point_zero );
411 int &locx = map_tile.pos_.x;
412 int &locy = map_tile.pos_.y;
413 const point sm_offset( submap.x * SEEX, submap.y * SEEY );
414
415 // Loop through all tiles in this submap indicated by current_submap
416 for( locx = 0; locx < SEEX; locx++ ) {
417 for( locy = 0; locy < SEEY; locy++ ) {
418 // Get a reference to the field variable from the submap;
419 // contains all the pointers to the real field effects.
420 field &curfield = current_submap->get_field( { static_cast<int>( locx ), static_cast<int>( locy ) } );
421
422 // when displayed_field_type == fd_null it means that `curfield` has no fields inside
423 // avoids instantiating (relatively) expensive map iterator
424 if( !curfield.displayed_field_type() ) {
425 continue;
426 }
427
428 // This is a translation from local coordinates to submap coordinates.
429 // All submaps are in one long 1d array.
430 thep.x = locx + sm_offset.x;
431 thep.y = locy + sm_offset.y;
432 // A const reference to the tripoint above, so that the code below doesn't accidentally change it
433 const tripoint &p = thep;
434
435 // This should be true only when the field in the current tile changes transparency state,
436 // More correctly: not just when the field is opaque, but when it changes state
437 // to a more/less transparent one
438 bool dirty_transparency_cache = false;
439
440 for( auto it = curfield.begin(); it != curfield.end(); ) {
441 // Iterating through all field effects in the submap's field.
442 field_entry &cur = it->second;
443
444 // Holds cur.get_field_type() as that is what the old system used before rewrite.
445 field_type_id cur_fd_type_id = cur.get_field_type();
446
447 // The field might have been killed by processing a neighbor field
448 if( !cur.is_field_alive() ) {
449 if( !cur_fd_type_id->get_transparent( cur.get_field_intensity() - 1 ) ) {
450 dirty_transparency_cache = true;
451 }
452 --current_submap->field_count;
453 curfield.remove_field( it++ );
454 continue;
455 }
456
457 // Again, legacy support in the event someone Mods set_field_intensity to allow more values.
458 if( cur.get_field_intensity() > 3 || cur.get_field_intensity() < 1 ) {
459 // TODO: Remove this eventually as we would suppoort more than 3 field intensity levels
460 debugmsg( "Whoooooa intensity of %d", cur.get_field_intensity() );
461 }
462
463 dirty_transparency_cache |= cur_fd_type_id->dirty_transparency_cache;
464
465 // Don't process "newborn" fields. This gives the player time to run if they need to.
466 if( cur.get_field_age() == 0_turns ) {
467 cur_fd_type_id = fd_null;
468 }
469
470 const field_type &cur_fd_type = *cur_fd_type_id;
471
472 // Upgrade field intensity
473 if( cur.intensity_upgrade_chance() > 0 &&
475 cur.intensity_upgrade_duration() > 0_turns &&
478 }
479
480 int part;
481 const ter_t &ter = map_tile.get_ter_t();
482 // Dissipate faster in water
483 if( ter.has_flag( TFLAG_SWIMMABLE ) ) {
485 }
486 if( cur_fd_type_id == fd_acid ) {
487 // Try to fall by a z-level
488 if( zlevels && p.z > -OVERMAP_DEPTH ) {
489 tripoint dst{ p.xy(), p.z - 1 };
490 if( valid_move( p, dst, true, true ) ) {
491 field_entry *acid_there = field_at( dst ).find_field( fd_acid );
492 if( acid_there == nullptr ) {
494 } else {
495 // Math can be a bit off,
496 // but "boiling" falling acid can be allowed to be stronger
497 // than acid that just lies there
498 const int sum_intensity = cur.get_field_intensity() + acid_there->get_field_intensity();
499 const int new_intensity = std::min( 3, sum_intensity );
500 // No way to get precise elapsed time, let's always reset
501 // Allow falling acid to last longer than regular acid to show it off
502 const time_duration new_age = -1_minutes * ( sum_intensity - new_intensity );
503 acid_there->set_field_intensity( new_intensity );
504 acid_there->set_field_age( new_age );
505 }
506
507 // Set ourselves up for removal
508 cur.set_field_intensity( 0 );
509 }
510 }
511 // TODO: Allow spreading to the sides if age < 0 && intensity == 3
512 }
513 if( cur_fd_type.apply_slime_factor > 0 ) {
514 sblk.apply_slime( p, cur.get_field_intensity() * cur_fd_type.apply_slime_factor );
515 }
516 if( cur_fd_type_id == fd_fire ) {
517 cur.set_field_age( std::max( -24_hours, cur.get_field_age() ) );
518 // Entire objects for ter/frn for flags
519 const ter_t &ter = map_tile.get_ter_t();
520 const furn_t &frn = map_tile.get_furn_t();
521
522 // We've got ter/furn cached, so let's use that
523 const bool is_sealed = ter_furn_has_flag( ter, frn, TFLAG_SEALED ) &&
525 // Consumed items count
526 int consumed = 0;
527 // How much time to add to the fire's life due to burned items/terrain/furniture
528 time_duration time_added = 0_turns;
529 // Checks if the fire can spread
530 const bool can_spread = !ter_furn_has_flag( ter, frn, TFLAG_FIRE_CONTAINER );
531 const bool no_floor = ter.has_flag( TFLAG_NO_FLOOR );
532 // If the flames are in furniture with fire_container flag like brazier or oven,
533 // they're fully contained, so skip consuming terrain
534 const bool can_burn = !no_floor && can_spread &&
535 ( check_flammable( ter ) || check_flammable( frn ) );
536 // The huge indent below should probably be somehow moved away from here
537 // without forcing the function to use i_at( p ) for fires without items
538 if( !is_sealed && map_tile.get_item_count() > 0 ) {
539 map_stack items_here = i_at( p );
540 std::vector<item> new_content;
541 for( auto explosive = items_here.begin(); explosive != items_here.end(); ) {
542 if( explosive->will_explode_in_fire() ) {
543 // We need to make a copy because the iterator validity is not predictable
544 item copy = *explosive;
545 explosive = items_here.erase( explosive );
546 if( copy.detonate( p, new_content ) ) {
547 // Need to restart, iterators may not be valid
548 explosive = items_here.begin();
549 }
550 } else {
551 ++explosive;
552 }
553 }
554
555 fire_data frd( cur.get_field_intensity(), !can_spread );
556 // The highest # of items this fire can remove in one turn
557 int max_consume = cur.get_field_intensity() * 2;
558
559 for( auto fuel = items_here.begin(); fuel != items_here.end() && consumed < max_consume; ) {
560 // `item::burn` modifies the charges in order to simulate some of them getting
561 // destroyed by the fire, this changes the item weight, but may not actually
562 // destroy it. We need to spawn products anyway.
563 const units::mass old_weight = fuel->weight( false );
564 bool destroyed = fuel->burn( frd );
565 // If the item is considered destroyed, it may have negative charge count,
566 // see `item::burn?. This in turn means `item::weight` returns a negative value,
567 // which we can not use, so only call `weight` when it's still an existing item.
568 const units::mass new_weight = destroyed ? 0_gram : fuel->weight( false );
569 if( old_weight != new_weight ) {
570 create_burnproducts( p, *fuel, old_weight - new_weight );
571 }
572
573 if( destroyed ) {
574 // If we decided the item was destroyed by fire, remove it.
575 // But remember its contents, except for irremovable mods, if any
576 const std::list<item *> content_list = fuel->contents.all_items_top();
577 for( item *it : content_list ) {
578 if( !it->is_irremovable() ) {
579 new_content.push_back( item( *it ) );
580 }
581 }
582 fuel = items_here.erase( fuel );
583 consumed++;
584 } else {
585 ++fuel;
586 }
587 }
588
589 spawn_items( p, new_content );
590 time_added = 1_turns * roll_remainder( frd.fuel_produced );
591 }
592
593 // Get the part of the vehicle in the fire (_internal skips the boundary check)
594 vehicle *veh = veh_at_internal( p, part );
595 if( veh != nullptr ) {
596 veh->damage( part, cur.get_field_intensity() * 10, DT_HEAT, true );
597 // Damage the vehicle in the fire.
598 }
599 if( can_burn ) {
600 if( ter.has_flag( TFLAG_SWIMMABLE ) ) {
601 // Flames die quickly on water
602 cur.set_field_age( cur.get_field_age() + 4_minutes );
603 }
604
605 // Consume the terrain we're on
606 if( ter_furn_has_flag( ter, frn, TFLAG_FLAMMABLE ) ) {
607 // The fire feeds on the ground itself until max intensity.
608 time_added += 1_turns * ( 5 - cur.get_field_intensity() );
609 if( cur.get_field_intensity() > 1 &&
610 one_in( 200 - cur.get_field_intensity() * 50 ) ) {
611 destroy( p, false );
612 }
613
614 } else if( ter_furn_has_flag( ter, frn, TFLAG_FLAMMABLE_HARD ) &&
615 one_in( 3 ) ) {
616 // The fire feeds on the ground itself until max intensity.
617 time_added += 1_turns * ( 4 - cur.get_field_intensity() );
618 if( cur.get_field_intensity() > 1 &&
619 one_in( 200 - cur.get_field_intensity() * 50 ) ) {
620 destroy( p, false );
621 }
622
623 } else if( ter.has_flag( TFLAG_FLAMMABLE_ASH ) ) {
624 // The fire feeds on the ground itself until max intensity.
625 time_added += 1_turns * ( 5 - cur.get_field_intensity() );
626 if( cur.get_field_intensity() > 1 &&
627 one_in( 200 - cur.get_field_intensity() * 50 ) ) {
628 if( p.z > 0 ) {
629 // We're in the air
630 ter_set( p, t_open_air );
631 } else {
632 ter_set( p, t_dirt );
633 }
634 }
635
636 } else if( frn.has_flag( TFLAG_FLAMMABLE_ASH ) ) {
637 // The fire feeds on the ground itself until max intensity.
638 time_added += 1_turns * ( 5 - cur.get_field_intensity() );
639 if( cur.get_field_intensity() > 1 &&
640 one_in( 200 - cur.get_field_intensity() * 50 ) ) {
641 furn_set( p, f_ash );
642 add_item_or_charges( p, item( "ash" ) );
643 }
644
645 }
646 }
647
648 if( ter.has_flag( TFLAG_NO_FLOOR ) && zlevels && p.z > -OVERMAP_DEPTH ) {
649 // We're hanging in the air - let's fall down
650 tripoint dst{ p.xy(), p.z - 1 };
651 if( valid_move( p, dst, true, true ) ) {
652 maptile dst_tile = maptile_at_internal( dst );
653 field_entry *fire_there = dst_tile.find_field( fd_fire );
654 if( fire_there == nullptr ) {
655 add_field( dst, fd_fire, 1, 0_turns, false );
657 } else {
658 // Don't fuel raging fires or they'll burn forever
659 // as they can produce small fires above themselves
660 int new_intensity = std::max( cur.get_field_intensity(),
661 fire_there->get_field_intensity() );
662 // Allow smaller fires to combine
663 if( new_intensity < 3 &&
664 cur.get_field_intensity() == fire_there->get_field_intensity() ) {
665 new_intensity++;
666 }
667 // A raging fire below us can support us for a while
668 // Otherwise decay and decay fast
669 if( fire_there->get_field_intensity() < 3 || one_in( 10 ) ) {
671 }
672 fire_there->set_field_intensity( new_intensity );
673 }
674 break;
675 }
676 }
677 // Lower age is a longer lasting fire
678 if( time_added != 0_turns ) {
679 cur.set_field_age( cur.get_field_age() - time_added );
680 } else if( can_burn ) {
681 // Nothing to burn = fire should be dying out faster
682 // Drain more power from big fires, so that they stop raging over nothing
683 // Except for fires on stoves and fireplaces, those are made to keep the fire alive
684 cur.mod_field_age( 10_seconds * cur.get_field_intensity() );
685 }
686
687 // Allow raging fires (and only raging fires) to spread up
688 // Spreading down is achieved by wrecking the walls/floor and then falling
689 if( zlevels && cur.get_field_intensity() == 3 && p.z < OVERMAP_HEIGHT ) {
690 const tripoint dst_p = tripoint( p.xy(), p.z + 1 );
691 // Let it burn through the floor
692 maptile dst = maptile_at_internal( dst_p );
693 const auto &dst_ter = dst.get_ter_t();
694 if( dst_ter.has_flag( TFLAG_NO_FLOOR ) ||
695 dst_ter.has_flag( TFLAG_FLAMMABLE ) ||
696 dst_ter.has_flag( TFLAG_FLAMMABLE_ASH ) ||
697 dst_ter.has_flag( TFLAG_FLAMMABLE_HARD ) ) {
698 field_entry *nearfire = dst.find_field( fd_fire );
699 if( nearfire != nullptr ) {
700 nearfire->mod_field_age( -2_turns );
701 } else {
702 add_field( dst_p, fd_fire, 1, 0_turns, false );
703 }
704 // Fueling fires above doesn't cost fuel
705 }
706 }
707
708 // Below we will access our nearest 8 neighbors, so let's cache them now
709 // This should probably be done more globally, because large fires will re-do it a lot
710 auto neighs = get_neighbors( p );
711
712 // If the flames are in a pit, it can't spread to non-pit
713 const bool in_pit = can_spread && ter.id.id() == t_pit;
714
715 // Count adjacent fires, to optimize out needless smoke and hot air
716 int adjacent_fires = 0;
717
718 // If the flames are big, they contribute to adjacent flames
719 if( can_spread ) {
720 if( cur.get_field_intensity() > 1 && one_in( 3 ) ) {
721 // Basically: Scan around for a spot,
722 // if there is more fire there, make it bigger and give it some fuel.
723 // This is how big fires spend their excess age:
724 // making other fires bigger. Flashpoint.
725 size_t end_it = static_cast<size_t>( rng( 0, neighs.size() - 1 ) );
726 for( size_t i = ( end_it + 1 ) % neighs.size(), count = 0;
727 count != neighs.size() && cur.get_field_age() < 0_turns;
728 i = ( i + 1 ) % neighs.size(), count++ ) {
729 maptile &dst = neighs[i].second;
730 auto dstfld = dst.find_field( fd_fire );
731 // If the fire exists and is weaker than ours, boost it
732 if( dstfld != nullptr &&
733 ( dstfld->get_field_intensity() <= cur.get_field_intensity() ||
734 dstfld->get_field_age() > cur.get_field_age() ) &&
735 ( in_pit == ( dst.get_ter() == t_pit ) ) ) {
736 if( dstfld->get_field_intensity() < 2 ) {
737 dstfld->set_field_intensity( dstfld->get_field_intensity() + 1 );
738 }
739
740 dstfld->set_field_age( dstfld->get_field_age() - 5_minutes );
741 cur.set_field_age( cur.get_field_age() + 5_minutes );
742 }
743 if( dstfld != nullptr ) {
744 adjacent_fires++;
745 }
746 }
747 } else if( cur.get_field_age() < 0_turns && cur.get_field_intensity() < 3 ) {
748 // See if we can grow into a stage 2/3 fire, for this
749 // burning neighbors are necessary in addition to
750 // field age < 0, or alternatively, a LOT of fuel.
751
752 // The maximum fire intensity is 1 for a lone fire, 2 for at least 1 neighbor,
753 // 3 for at least 2 neighbors.
754 int maximum_intensity = 1;
755
756 // The following logic looks a bit complex due to optimization concerns, so here are the semantics:
757 // 1. Calculate maximum field intensity based on fuel, -50 minutes is 2(medium), -500 minutes is 3(raging)
758 // 2. Calculate maximum field intensity based on neighbors, 3 neighbors is 2(medium), 7 or more neighbors is 3(raging)
759 // 3. Pick the higher maximum between 1. and 2.
760 if( cur.get_field_age() < -500_minutes ) {
761 maximum_intensity = 3;
762 } else {
763 for( auto &neigh : neighs ) {
764 if( neigh.second.get_field().find_field( fd_fire ) != nullptr ) {
765 adjacent_fires++;
766 }
767 }
768 maximum_intensity = 1 + ( adjacent_fires >= 3 ) + ( adjacent_fires >= 7 );
769
770 if( maximum_intensity < 2 && cur.get_field_age() < -50_minutes ) {
771 maximum_intensity = 2;
772 }
773 }
774
775 // If we consumed a lot, the flames grow higher
776 if( cur.get_field_intensity() < maximum_intensity && cur.get_field_age() < 0_turns ) {
777 // Fires under 0 age grow in size. Level 3 fires under 0 spread later on.
778 // Weaken the newly-grown fire
780 cur.set_field_age( cur.get_field_age() + 10_minutes * cur.get_field_intensity() );
781 }
782 }
783
784 // Consume adjacent fuel / terrain / webs to spread.
785 // Our iterator will start at end_i + 1 and increment from there and then wrap around.
786 // This guarantees it will check all neighbors, starting from a random one
787 const size_t end_i = static_cast<size_t>( rng( 0, neighs.size() - 1 ) );
788 for( size_t i = ( end_i + 1 ) % neighs.size(), count = 0;
789 count != neighs.size();
790 i = ( i + 1 ) % neighs.size(), count++ ) {
791 if( one_in( cur.get_field_intensity() * 2 ) ) {
792 // Skip some processing to save on CPU
793 continue;
794 }
795
796 tripoint &dst_p = neighs[i].first;
797 maptile &dst = neighs[i].second;
798 // No bounds checking here: we'll treat the invalid neighbors as valid.
799 // We're using the map tile wrapper, so we can treat invalid tiles as sentinels.
800 // This will create small oddities on map edges, but nothing more noticeable than
801 // "cut-off" that happens with bounds checks.
802
803 field_entry *nearfire = dst.find_field( fd_fire );
804 if( nearfire != nullptr ) {
805 // We handled supporting fires in the section above, no need to do it here
806 continue;
807 }
808
809 field_entry *nearwebfld = dst.find_field( fd_web );
810 int spread_chance = 25 * ( cur.get_field_intensity() - 1 );
811 if( nearwebfld != nullptr ) {
812 spread_chance = 50 + spread_chance / 2;
813 }
814
815 const ter_t &dster = dst.get_ter_t();
816 const furn_t &dsfrn = dst.get_furn_t();
817 // Allow weaker fires to spread occasionally
818 const int power = cur.get_field_intensity() + one_in( 5 );
819 if( can_spread && rng( 1, 100 ) < spread_chance &&
820 ( check_flammable( dster ) || check_flammable( dsfrn ) ) &&
821 ( in_pit == ( dster.id.id() == t_pit ) ) &&
822 (
823 ( power >= 3 && cur.get_field_age() < 0_turns && one_in( 20 ) ) ||
824 ( power >= 2 && ( ter_furn_has_flag( dster, dsfrn, TFLAG_FLAMMABLE ) && one_in( 2 ) ) ) ||
825 ( power >= 2 && ( ter_furn_has_flag( dster, dsfrn, TFLAG_FLAMMABLE_ASH ) && one_in( 2 ) ) ) ||
826 ( power >= 3 && ( ter_furn_has_flag( dster, dsfrn, TFLAG_FLAMMABLE_HARD ) && one_in( 5 ) ) ) ||
827 nearwebfld || ( dst.get_item_count() > 0 &&
829 one_in( 5 ) )
830 ) ) {
831 // Nearby open flammable ground? Set it on fire.
832 add_field( dst_p, fd_fire, 1, 0_turns, false );
833 tmpfld = dst.find_field( fd_fire );
834 if( tmpfld != nullptr ) {
835 // Make the new fire quite weak, so that it doesn't start jumping around instantly
836 tmpfld->set_field_age( 2_minutes );
837 // Consume a bit of our fuel
838 cur.set_field_age( cur.get_field_age() + 1_minutes );
839 }
840 if( nearwebfld ) {
841 nearwebfld->set_field_intensity( 0 );
842 }
843 }
844 }
845 }
846 }
847
848 // Spread gaseous fields
849 if( cur.gas_can_spread() ) {
850 const int gas_percent_spread = cur_fd_type.percent_spread;
851 if( gas_percent_spread > 0 ) {
852 const time_duration outdoor_age_speedup = cur_fd_type.outdoor_age_speedup;
853 spread_gas( cur, p, gas_percent_spread, outdoor_age_speedup, sblk );
854 }
855 }
856
857 if( cur_fd_type_id == fd_fungal_haze ) {
858 if( one_in( 10 - 2 * cur.get_field_intensity() ) ) {
859 // Haze'd terrain
860 fungal_effects( *g, here ).spread_fungus( p );
861 }
862 }
863
864 // Process npc complaints
865 const std::tuple<int, std::string, time_duration, std::string> &npc_complain_data =
866 cur_fd_type.npc_complain_data;
867 const int chance = std::get<0>( npc_complain_data );
868 if( chance > 0 && one_in( chance ) ) {
869 if( npc *const np = g->critter_at<npc>( p, false ) ) {
870 np->complain_about( std::get<1>( npc_complain_data ),
871 std::get<2>( npc_complain_data ),
872 std::get<3>( npc_complain_data ) );
873 }
874 }
875
876 // Apply radiation
877 if( cur.extra_radiation_max() > 0 ) {
878 int extra_radiation = rng( cur.extra_radiation_min(), cur.extra_radiation_max() );
879 adjust_radiation( p, extra_radiation );
880 }
881
882 // Apply wandering fields from vents
883 if( cur_fd_type.wandering_field ) {
884 for( const tripoint &pnt : points_in_radius( p, cur.get_field_intensity() - 1 ) ) {
885 field &wandering_field = get_field( pnt );
886 tmpfld = wandering_field.find_field( cur_fd_type.wandering_field );
887 if( tmpfld && tmpfld->get_field_intensity() < cur.get_field_intensity() ) {
888 tmpfld->set_field_intensity( tmpfld->get_field_intensity() + 1 );
889 } else {
890 add_field( pnt, cur_fd_type.wandering_field, cur.get_field_intensity() );
891 }
892 }
893 }
894
895 if( cur_fd_type_id == fd_fire_vent ) {
896
897 if( cur.get_field_intensity() > 1 ) {
898 if( one_in( 3 ) ) {
900 }
902 } else {
903 dirty_transparency_cache = true;
904 add_field( p, fd_flame_burst, 3, cur.get_field_age() );
905 cur.set_field_intensity( 0 );
906 }
907 }
908 if( cur_fd_type_id == fd_flame_burst ) {
909 if( cur.get_field_intensity() > 1 ) {
912 } else {
913 dirty_transparency_cache = true;
914 add_field( p, fd_fire_vent, 3, cur.get_field_age() );
915 cur.set_field_intensity( 0 );
916 }
917 }
918 if( cur_fd_type_id == fd_electricity ) {
919 // 4 in 5 chance to spread
920 if( !one_in( 5 ) ) {
921 std::vector<tripoint> valid;
922 // We're grounded
923 if( impassable( p ) && cur.get_field_intensity() > 1 ) {
924 int tries = 0;
925 tripoint pnt;
926 pnt.z = p.z;
927 while( tries < 10 && cur.get_field_age() < 5_minutes && cur.get_field_intensity() > 1 ) {
928 pnt.x = p.x + rng( -1, 1 );
929 pnt.y = p.y + rng( -1, 1 );
930 if( passable( pnt ) && !obstructed_by_vehicle_rotation( p, pnt ) ) {
931 add_field( pnt, fd_electricity, 1, cur.get_field_age() + 1_turns );
933 tries = 0;
934 } else {
935 tries++;
936 }
937 }
938 // We're not grounded; attempt to ground
939 } else {
940 for( const tripoint &dst : points_in_radius( p, 1 ) ) {
941 // Grounded tiles first
942 if( impassable( dst ) ) {
943 valid.push_back( dst );
944 }
945 }
946 // Spread to adjacent space, then
947 if( valid.empty() ) {
948 tripoint dst( p + point( rng( -1, 1 ), rng( -1, 1 ) ) );
949 field_entry *elec = get_field( dst ).find_field( fd_electricity );
950 bool pass = passable( dst ) && !obstructed_by_vehicle_rotation( p, dst );
951 if( pass && elec != nullptr &&
952 elec->get_field_intensity() < 3 ) {
953 elec->set_field_intensity( elec->get_field_intensity() + 1 );
955 } else if( pass ) {
956 add_field( dst, fd_electricity, 1, cur.get_field_age() + 1_turns );
957 }
959 }
960 while( !valid.empty() && cur.get_field_intensity() > 1 ) {
961 const tripoint target = random_entry_removed( valid );
962 add_field( target, fd_electricity, 1, cur.get_field_age() + 1_turns );
964 }
965 }
966 }
967 }
968
969 int monster_spawn_chance = cur.monster_spawn_chance();
970 int monster_spawn_count = cur.monster_spawn_count();
971 if( monster_spawn_count > 0 && monster_spawn_chance > 0 && one_in( monster_spawn_chance ) ) {
972 for( ; monster_spawn_count > 0; monster_spawn_count-- ) {
974 cur.monster_spawn_group(), &monster_spawn_count );
975 if( !spawn_details.name ) {
976 continue;
977 }
980 [this]( const tripoint & n ) {
981 return passable( n );
982 } ) ) {
983 add_spawn( spawn_details.name, spawn_details.pack_size, *spawn_point );
984 }
985 }
986 }
987
988 if( cur_fd_type_id == fd_push_items ) {
989 map_stack items = i_at( p );
990 for( auto pushee = items.begin(); pushee != items.end(); ) {
991 if( pushee->typeId() != itype_rock ||
992 pushee->age() < 1_turns ) {
993 pushee++;
994 } else {
995 item tmp = *pushee;
996 tmp.set_age( 0_turns );
997 pushee = items.erase( pushee );
998 std::vector<tripoint> valid;
999 for( const tripoint &dst : points_in_radius( p, 1 ) ) {
1000 if( get_field( dst, fd_push_items ) != nullptr ) {
1001 valid.push_back( dst );
1002 }
1003 }
1004 if( !valid.empty() ) {
1005 tripoint newp = random_entry( valid );
1006 add_item_or_charges( newp, tmp );
1007 if( g->u.pos() == newp ) {
1008 add_msg( m_bad, _( "A %s hits you!" ), tmp.tname() );
1009 const bodypart_id hit = g->u.get_random_body_part();
1010 g->u.deal_damage( nullptr, hit, damage_instance( DT_BASH, 6 ) );
1011 g->u.check_dead_state();
1012 }
1013
1014 if( npc *const p = g->critter_at<npc>( newp ) ) {
1015 // TODO: combine with player character code above
1016 const bodypart_id hit = g->u.get_random_body_part();
1017 p->deal_damage( nullptr, hit, damage_instance( DT_BASH, 6 ) );
1018 if( g->u.sees( newp ) ) {
1019 add_msg( _( "A %1$s hits %2$s!" ), tmp.tname(), p->name );
1020 }
1021 p->check_dead_state();
1022 } else if( monster *const mon = g->critter_at<monster>( newp ) ) {
1023 mon->apply_damage( nullptr, bodypart_id( "torso" ),
1024 6 - mon->get_armor_bash( bodypart_id( "torso" ) ) );
1025 if( g->u.sees( newp ) ) {
1026 add_msg( _( "A %1$s hits the %2$s!" ), tmp.tname(), mon->name() );
1027 }
1028 mon->check_dead_state();
1029 }
1030 }
1031 }
1032 }
1033 }
1034 if( cur_fd_type_id == fd_shock_vent ) {
1035 if( cur.get_field_intensity() > 1 ) {
1036 if( one_in( 5 ) ) {
1038 }
1039 } else {
1040 cur.set_field_intensity( 3 );
1041 int num_bolts = rng( 3, 6 );
1042 for( int i = 0; i < num_bolts; i++ ) {
1043 int xdir = 0;
1044 int ydir = 0;
1045 while( xdir == 0 && ydir == 0 ) {
1046 xdir = rng( -1, 1 );
1047 ydir = rng( -1, 1 );
1048 }
1049 int dist = rng( 4, 12 );
1050 int boltx = p.x;
1051 int bolty = p.y;
1052 for( int n = 0; n < dist; n++ ) {
1053 boltx += xdir;
1054 bolty += ydir;
1055 add_field( tripoint( boltx, bolty, p.z ), fd_electricity, rng( 2, 3 ) );
1056 if( one_in( 4 ) ) {
1057 if( xdir == 0 ) {
1058 xdir = rng( 0, 1 ) * 2 - 1;
1059 } else {
1060 xdir = 0;
1061 }
1062 }
1063 if( one_in( 4 ) ) {
1064 if( ydir == 0 ) {
1065 ydir = rng( 0, 1 ) * 2 - 1;
1066 } else {
1067 ydir = 0;
1068 }
1069 }
1070 }
1071 }
1072 }
1073 }
1074 if( cur_fd_type_id == fd_acid_vent ) {
1075
1076 if( cur.get_field_intensity() > 1 ) {
1077 if( cur.get_field_age() >= 1_minutes ) {
1079 cur.set_field_age( 0_turns );
1080 }
1081 } else {
1082 cur.set_field_intensity( 3 );
1083 for( const tripoint &t : points_in_radius( p, 5 ) ) {
1084 const field_entry *acid = get_field( t, fd_acid );
1085 if( acid != nullptr && acid->get_field_intensity() == 0 ) {
1086 int new_intensity = 3 - rl_dist( p, t ) / 2 + ( one_in( 3 ) ? 1 : 0 );
1087 if( new_intensity > 3 ) {
1088 new_intensity = 3;
1089 }
1090 if( new_intensity > 0 ) {
1091 add_field( t, fd_acid, new_intensity );
1092 }
1093 }
1094 }
1095 }
1096 }
1097 if( cur_fd_type_id == fd_bees ) {
1098 // Poor bees are vulnerable to so many other fields.
1099 // TODO: maybe adjust effects based on different fields.
1100 if( curfield.find_field( fd_web ) ||
1101 curfield.find_field( fd_fire ) ||
1102 curfield.find_field( fd_smoke ) ||
1103 curfield.find_field( fd_toxic_gas ) ||
1104 curfield.find_field( fd_tear_gas ) ||
1105 curfield.find_field( fd_relax_gas ) ||
1106 curfield.find_field( fd_nuke_gas ) ||
1107 curfield.find_field( fd_gas_vent ) ||
1108 curfield.find_field( fd_smoke_vent ) ||
1109 curfield.find_field( fd_fungicidal_gas ) ||
1110 curfield.find_field( fd_insecticidal_gas ) ||
1111 curfield.find_field( fd_fire_vent ) ||
1112 curfield.find_field( fd_flame_burst ) ||
1113 curfield.find_field( fd_electricity ) ||
1114 curfield.find_field( fd_fatigue ) ||
1115 curfield.find_field( fd_shock_vent ) ||
1116 curfield.find_field( fd_plasma ) ||
1117 curfield.find_field( fd_laser ) ||
1118 curfield.find_field( fd_dazzling ) ||
1119 curfield.find_field( fd_electricity ) ||
1120 curfield.find_field( fd_incendiary ) ) {
1121 // Kill them at the end of processing.
1122 cur.set_field_intensity( 0 );
1123 } else {
1124 // Bees chase the player if in range, wander randomly otherwise.
1125 if( !g->u.is_underwater() &&
1126 rl_dist( p, g->u.pos() ) < 10 &&
1127 clear_path( p, g->u.pos(), 10, 1, 100 ) ) {
1128
1129 std::vector<point> candidate_positions =
1130 squares_in_direction( p.xy(), point( g->u.posx(), g->u.posy() ) );
1131 for( const point &candidate_position : candidate_positions ) {
1132 field &target_field = get_field( tripoint( candidate_position, p.z ) );
1133 // Only shift if there are no bees already there.
1134 // TODO: Figure out a way to merge bee fields without allowing
1135 // Them to effectively move several times in a turn depending
1136 // on iteration direction.
1137 if( !target_field.find_field( fd_bees ) ) {
1138 add_field( tripoint( candidate_position, p.z ), fd_bees,
1139 cur.get_field_intensity(), cur.get_field_age() );
1140 cur.set_field_intensity( 0 );
1141 break;
1142 }
1143 }
1144 } else {
1145 spread_gas( cur, p, 5, 0_turns, sblk );
1146 }
1147 }
1148 }
1149 if( cur_fd_type_id == fd_incendiary ) {
1150 // Needed for variable scope
1151 tripoint dst( p + point( rng( -1, 1 ), rng( -1, 1 ) ) );
1152 if( has_flag( TFLAG_FLAMMABLE, dst ) ||
1153 has_flag( TFLAG_FLAMMABLE_ASH, dst ) ||
1154 has_flag( TFLAG_FLAMMABLE_HARD, dst ) ) {
1155 add_field( dst, fd_fire, 1 );
1156 }
1157
1158 // Check piles for flammable items and set those on fire
1159 if( flammable_items_at( dst ) ) {
1160 add_field( dst, fd_fire, 1 );
1161 }
1162
1164 }
1165 if( cur_fd_type_id == fd_fungicidal_gas ) {
1166 // Check the terrain and replace it accordingly to simulate the fungus dieing off
1167 const ter_t &ter = map_tile.get_ter_t();
1168 const furn_t &frn = map_tile.get_furn_t();
1169 const int intensity = cur.get_field_intensity();
1170 if( ter.has_flag( flag_FUNGUS ) && one_in( 10 / intensity ) ) {
1171 ter_set( p, t_dirt );
1172 }
1173 if( frn.has_flag( flag_FUNGUS ) && one_in( 10 / intensity ) ) {
1174 furn_set( p, f_null );
1175 }
1176 }
1177
1178 cur.set_field_age( cur.get_field_age() + 1_turns );
1179 auto &fdata = cur.get_field_type().obj();
1180 if( fdata.half_life > 0_turns && cur.get_field_age() > 0_turns &&
1181 dice( 2, to_turns<int>( cur.get_field_age() ) ) > to_turns<int>( fdata.half_life ) ) {
1182 cur.set_field_age( 0_turns );
1184 }
1185 if( !cur.is_field_alive() ) {
1186 --current_submap->field_count;
1187 curfield.remove_field( it++ );
1188 } else {
1189 ++it;
1190 }
1191 }
1192
1193 if( dirty_transparency_cache ) {
1195 set_seen_cache_dirty( thep );
1196 }
1197 }
1198 }
1199 const int minz = zlevels ? -OVERMAP_DEPTH : abs_sub.z;
1200 const int maxz = zlevels ? OVERMAP_HEIGHT : abs_sub.z;
1201 for( int z = std::max( submap.z - 1, minz ); z <= std::min( submap.z + 1, maxz ); ++z ) {
1202 auto &field_cache = get_cache( z ).field_cache;
1203 for( int y = std::max( submap.y - 1, 0 ); y <= std::min( submap.y + 1, MAPSIZE - 1 ); ++y ) {
1204 for( int x = std::max( submap.x - 1, 0 ); x <= std::min( submap.x + 1, MAPSIZE - 1 ); ++x ) {
1205 if( get_submap_at_grid( { x, y, z } )->field_count > 0 ) {
1206 field_cache.set( x + y * MAPSIZE );
1207 } else {
1208 field_cache.reset( x + y * MAPSIZE );
1209 }
1210 }
1211 }
1212 }
1213 sblk.commit_modifications();
1214}
bool gas_can_spread()
Definition: field.h:93
time_duration intensity_upgrade_duration() const
Definition: field.cpp:44
mongroup_id monster_spawn_group() const
Definition: field.cpp:64
time_duration get_underwater_age_speedup() const
Definition: field.h:97
int monster_spawn_count() const
Definition: field.cpp:54
time_duration mod_field_age(const time_duration &mod_age)
Adds given value to age.
Definition: field.h:73
int intensity_upgrade_chance() const
Definition: field.cpp:39
int monster_spawn_radius() const
Definition: field.cpp:59
int monster_spawn_chance() const
Definition: field.cpp:49
std::map< field_type_id, field_entry >::iterator begin()
Definition: field.cpp:251
std::map< field_type_id, field_entry >::iterator end()
Definition: field.cpp:261
void spread_fungus(const tripoint &p)
std::string tname(unsigned int quantity=1, bool with_prefix=true, unsigned int truncate=0) const
Return the (translated) item name.
Definition: item.cpp:4465
void set_age(const time_duration &age)
Definition: item.cpp:9858
bool detonate(const tripoint &p, std::vector< item > &drops)
Detonates the item and adds remains (if any) to drops.
Definition: item.cpp:8613
std::array< std::pair< tripoint, maptile >, 8 > get_neighbors(const tripoint &p)
Definition: map_field.cpp:190
void create_hot_air(const tripoint &p, int intensity)
Definition: map_field.cpp:363
bool clear_path(const tripoint &f, const tripoint &t, int range, int cost_min, int cost_max) const
Check whether there's a direct line of sight between F and T with the additional movecost restraints.
Definition: map.cpp:6394
void spread_gas(field_entry &cur, const tripoint &p, int percent_spread, const time_duration &outdoor_age_speedup, scent_block &sblk)
Definition: map_field.cpp:251
void create_burnproducts(const tripoint &p, const item &fuel, const units::mass &burned_mass)
Definition: map_field.cpp:96
field_type_id fd_laser
Definition: field_type.cpp:359
field_type_id fd_plasma
Definition: field_type.cpp:358
field_type_id fd_null
Definition: field_type.cpp:335
std::vector< point > squares_in_direction(const point &p1, const point &p2)
Definition: line.cpp:588
static const itype_id itype_rock("rock")
static bool check_flammable(const map_data_common_t &t)
Definition: map_field.cpp:354
static const std::string flag_FUNGUS("FUNGUS")
furn_id f_ash
Definition: mapdata.cpp:1097
ter_id t_pit
Definition: mapdata.cpp:625
@ TFLAG_FLAMMABLE_HARD
Definition: mapdata.h:294
@ TFLAG_FLAMMABLE
Definition: mapdata.h:277
@ TFLAG_FLAMMABLE_ASH
Definition: mapdata.h:289
@ TFLAG_FIRE_CONTAINER
Definition: mapdata.h:293
bool acid(monster *z)
Definition: monattack.cpp:585
bool get_transparent(int level=0) const
Definition: field_type.h:204
int percent_spread
Definition: field_type.h:157
field_type_id wandering_field
Definition: field_type.h:182
std::tuple< int, std::string, time_duration, std::string > npc_complain_data
Definition: field_type.h:170
time_duration outdoor_age_speedup
Definition: field_type.h:155
int apply_slime_factor
Definition: field_type.h:158
Contains the state of a fire in one tile on one turn.
Definition: fire.h:18
size_t get_item_count() const
Definition: submap.h:333
ter_id get_ter() const
Definition: submap.h:289

References _, abs_sub, mattack::acid(), add_field(), add_item_or_charges(), add_msg(), add_spawn(), adjust_radiation(), scent_block::apply_slime(), field_type::apply_slime_factor, field::begin(), item_stack::begin(), check_flammable(), clear_path(), scent_block::commit_modifications(), detail::count(), create_burnproducts(), create_hot_air(), vehicle::damage(), debugmsg, destroy(), destroyed, item::detonate(), dice(), field_type::dirty_transparency_cache, field::displayed_field_type(), DT_BASH, DT_HEAT, eight_horizontal_neighbors, field::end(), item_stack::end(), map_stack::erase(), explosive, field_entry::extra_radiation_max(), field_entry::extra_radiation_min(), f_ash, f_null, fd_acid, fd_acid_vent, fd_bees, fd_dazzling, fd_electricity, fd_fatigue, fd_fire, fd_fire_vent, fd_flame_burst, fd_fungal_haze, fd_fungicidal_gas, fd_gas_vent, fd_incendiary, fd_insecticidal_gas, fd_laser, fd_nuke_gas, fd_null, fd_plasma, fd_push_items, fd_relax_gas, fd_shock_vent, fd_smoke, fd_smoke_vent, fd_tear_gas, fd_toxic_gas, fd_web, field_at(), level_cache::field_cache, submap::field_count, maptile::find_field(), field::find_field(), flag_FUNGUS(), flammable_items_at(), fire_data::fuel_produced, furn_set(), g, field_entry::gas_can_spread(), get_cache(), submap::get_field(), get_field(), field_entry::get_field_age(), field_entry::get_field_intensity(), field_entry::get_field_type(), maptile::get_furn_t(), maptile::get_item_count(), get_map(), get_neighbors(), get_submap_at_grid(), maptile::get_ter(), maptile::get_ter_t(), field_type::get_transparent(), field_entry::get_underwater_age_speedup(), MonsterGroupManager::GetResultFromGroup(), map_data_common_t::has_flag(), has_flag(), i_at(), int_id< T >::id(), ter_t::id, string_id< T >::id(), impassable(), field_entry::intensity_upgrade_chance(), field_entry::intensity_upgrade_duration(), field_entry::is_field_alive(), itype_rock, m_bad, MAPSIZE, maptile_at_internal(), field_entry::mod_field_age(), field_entry::monster_spawn_chance(), field_entry::monster_spawn_count(), field_entry::monster_spawn_group(), field_entry::monster_spawn_radius(), MonsterGroupResult::name, field_type::npc_complain_data, int_id< T >::obj(), obstructed_by_vehicle_rotation(), calendar::once_every(), one_in(), field_type::outdoor_age_speedup, OVERMAP_DEPTH, OVERMAP_HEIGHT, MonsterGroupResult::pack_size, passable(), field_type::percent_spread, point_zero, points_in_radius(), maptile::pos_, random_entry(), random_entry_removed(), random_point(), field::remove_field(), rl_dist(), rng(), roll_remainder(), SEEX, SEEY, item::set_age(), field_entry::set_field_age(), field_entry::set_field_intensity(), set_seen_cache_dirty(), set_transparency_cache_dirty(), spawn_items(), fungal_effects::spread_fungus(), spread_gas(), squares_in_direction(), t_dirt, t_open_air, t_pit, ter(), ter_furn_has_flag(), ter_set(), TFLAG_ALLOW_FIELD_EFFECT, TFLAG_FIRE_CONTAINER, TFLAG_FLAMMABLE, TFLAG_FLAMMABLE_ASH, TFLAG_FLAMMABLE_HARD, TFLAG_NO_FLOOR, TFLAG_SEALED, TFLAG_SWIMMABLE, item::tname(), valid_move(), veh_at_internal(), field_type::wandering_field, point::x, tripoint::x, tripoint::xy(), point::y, tripoint::y, tripoint::z, and zlevels.

Referenced by process_fields().

◆ process_items()

void map::process_items ( )

Definition at line 4569 of file map.cpp.

4570{
4571 const int minz = zlevels ? -OVERMAP_DEPTH : abs_sub.z;
4572 const int maxz = zlevels ? OVERMAP_HEIGHT : abs_sub.z;
4573 for( int gz = minz; gz <= maxz; ++gz ) {
4574 level_cache &cache = access_cache( gz );
4575 std::set<tripoint> submaps_with_vehicles;
4576 for( vehicle *this_vehicle : cache.vehicle_list ) {
4577 tripoint pos = this_vehicle->global_pos3();
4578 submaps_with_vehicles.emplace( pos.x / SEEX, pos.y / SEEY, pos.z );
4579 }
4580 for( const tripoint &pos : submaps_with_vehicles ) {
4581 submap *const current_submap = get_submap_at_grid( pos );
4582 // Vehicles first in case they get blown up and drop active items on the map.
4583 process_items_in_vehicles( *current_submap );
4584 }
4585 }
4586 // Making a copy, in case the original variable gets modified during `process_items_in_submap`
4587 const std::set<tripoint> submaps_with_active_items_copy = submaps_with_active_items;
4588 for( const tripoint &abs_pos : submaps_with_active_items_copy ) {
4589 const tripoint local_pos = abs_pos - abs_sub.xy();
4590 submap *const current_submap = get_submap_at_grid( local_pos );
4591 if( !current_submap->active_items.empty() ) {
4592 process_items_in_submap( *current_submap, local_pos );
4593 }
4594 }
4595}
void process_items_in_vehicles(submap &current_submap)
Definition: map.cpp:4627
void process_items_in_submap(submap &current_submap, const tripoint &gridp)
Definition: map.cpp:4597

References abs_sub, access_cache(), submap::active_items, active_item_cache::empty(), get_submap_at_grid(), vehicle::global_pos3(), OVERMAP_DEPTH, OVERMAP_HEIGHT, wrapped_vehicle::pos, process_items_in_submap(), process_items_in_vehicles(), SEEX, SEEY, submaps_with_active_items, level_cache::vehicle_list, tripoint::x, tripoint::xy(), tripoint::y, tripoint::z, and zlevels.

Referenced by game::do_turn().

◆ process_items_in_submap()

void map::process_items_in_submap ( submap current_submap,
const tripoint gridp 
)
private

Definition at line 4597 of file map.cpp.

4598{
4599 // Get a COPY of the active item list for this submap.
4600 // If more are added as a side effect of processing, they are ignored this turn.
4601 // If they are destroyed before processing, they don't get processed.
4602 std::vector<item_reference> active_items = current_submap.active_items.get_for_processing();
4603 const point grid_offset( gridp.x * SEEX, gridp.y * SEEY );
4604 for( item_reference &active_item_ref : active_items ) {
4605 if( !active_item_ref.item_ref ) {
4606 // The item was destroyed, so skip it.
4607 continue;
4608 }
4609
4610 const tripoint map_location = tripoint( grid_offset + active_item_ref.location, gridp.z );
4611 // root cellars are special
4613 if( ter( map_location ) == t_rootcellar ) {
4615 }
4616 if( furn( map_location ) == f_fridge_on ) {
4618 }
4619 if( furn( map_location ) == f_minifreezer_on ) {
4621 }
4622 map_stack items = i_at( map_location );
4623 process_map_items( items, active_item_ref.item_ref, map_location, 1, flag );
4624 }
4625}
std::vector< item_reference > get_for_processing()
Returns the first size() / processing_speed() elements of each list, rounded up.
temperature_flag
Definition: enums.h:42
@ TEMP_NORMAL
Definition: enums.h:43
@ TEMP_FRIDGE
Definition: enums.h:45
@ TEMP_FREEZER
Definition: enums.h:46
@ TEMP_ROOT_CELLAR
Definition: enums.h:47
static bool process_map_items(item_stack &items, safe_reference< item > &item_ref, const tripoint &location, const float insulation, const temperature_flag flag)
Definition: map.cpp:4455
ter_id t_rootcellar
Definition: mapdata.cpp:711
furn_id f_minifreezer_on
Definition: mapdata.cpp:1106
furn_id f_fridge_on
Definition: mapdata.cpp:1106

References submap::active_items, f_fridge_on, f_minifreezer_on, furn(), active_item_cache::get_for_processing(), i_at(), process_map_items(), SEEX, SEEY, t_rootcellar, TEMP_FREEZER, TEMP_FRIDGE, TEMP_NORMAL, TEMP_ROOT_CELLAR, ter(), tripoint::x, tripoint::y, and tripoint::z.

Referenced by process_items().

◆ process_items_in_vehicle()

void map::process_items_in_vehicle ( vehicle cur_veh,
submap current_submap 
)
private

Definition at line 4648 of file map.cpp.

4649{
4650 const bool engine_heater_is_on = cur_veh.has_part( "E_HEATER", true ) && cur_veh.engine_on;
4651 for( const vpart_reference &vp : cur_veh.get_any_parts( VPFLAG_FLUIDTANK ) ) {
4652 vp.part().process_contents( vp.pos(), engine_heater_is_on );
4653 }
4654
4655 auto cargo_parts = cur_veh.get_parts_including_carried( VPFLAG_CARGO );
4656 for( const vpart_reference &vp : cargo_parts ) {
4657 process_vehicle_items( cur_veh, vp.part_index() );
4658 }
4659
4660 for( item_reference &active_item_ref : cur_veh.active_items.get_for_processing() ) {
4661 if( empty( cargo_parts ) ) {
4662 return;
4663 } else if( !active_item_ref.item_ref ) {
4664 // The item was destroyed, so skip it.
4665 continue;
4666 }
4667 const auto it = std::find_if( begin( cargo_parts ),
4668 end( cargo_parts ), [&]( const vpart_reference & part ) {
4669 return active_item_ref.location == part.mount();
4670 } );
4671
4672 if( it == end( cargo_parts ) ) {
4673 continue; // Can't find a cargo part matching the active item.
4674 }
4675 const item &target = *active_item_ref.item_ref;
4676 // Find the cargo part and coordinates corresponding to the current active item.
4677 const vehicle_part &pt = it->part();
4678 const tripoint item_loc = it->pos();
4679 auto items = cur_veh.get_items( static_cast<int>( it->part_index() ) );
4680 float it_insulation = 1.0;
4682 if( target.is_food() || target.is_food_container() || target.is_corpse() ) {
4683 const vpart_info &pti = pt.info();
4684 if( engine_heater_is_on ) {
4686 }
4687 // some vehicle parts provide insulation, default is 1
4688 it_insulation = pti.item->insulation_factor;
4689
4690 if( pt.enabled && pti.has_flag( VPFLAG_FRIDGE ) ) {
4691 it_insulation = 1; // ignore fridge insulation if on
4693 } else if( pt.enabled && pti.has_flag( VPFLAG_FREEZER ) ) {
4694 it_insulation = 1; // ignore freezer insulation if on
4696 }
4697 }
4698 if( !process_map_items( items, active_item_ref.item_ref, item_loc, it_insulation, flag ) ) {
4699 // If the item was NOT destroyed, we can skip the remainder,
4700 // which handles fallout from the vehicle being damaged.
4701 continue;
4702 }
4703
4704 // item does not exist anymore, might have been an exploding bomb,
4705 // check if the vehicle is still valid (does exist)
4706 if( !current_submap.contains_vehicle( &cur_veh ) ) {
4707 // Nope, vehicle is not in the vehicle list of the submap,
4708 // it might have moved to another submap (unlikely)
4709 // or be destroyed, anyway it does not need to be processed here
4710 return;
4711 }
4712
4713 // Vehicle still valid, reload the list of cargo parts,
4714 // the list of cargo parts might have changed (imagine a part with
4715 // a low index has been removed by an explosion, all the other
4716 // parts would move up to fill the gap).
4717 cargo_parts = cur_veh.get_any_parts( VPFLAG_CARGO );
4718 }
4719}
bool is_food_container() const
Definition: item.cpp:6479
bool is_corpse() const
Whether this is a corpse item.
Definition: item.cpp:6491
bool contains_vehicle(vehicle *)
Definition: submap.cpp:220
bool engine_on
Definition: vehicle.h:1989
vehicle_part_with_feature_range< std::string > get_parts_including_carried(std::string feature) const
Yields a range of parts of this vehicle that each have the given feature and are not broken or remove...
Definition: vehicle.cpp:2730
bool has_part(const std::string &flag, bool enabled=false) const
Check if vehicle has at least one unbroken part with specified flag.
Definition: vehicle.cpp:2560
active_item_cache active_items
Definition: vehicle.h:1864
vehicle_part_with_feature_range< std::string > get_any_parts(std::string feature) const
Yields a range of parts of this vehicle that each have the given feature and not removed.
Definition: vehicle.cpp:2744
itype_id item
base item for this part
Definition: veh_type.h:152
point mount() const
Returns the mount point: the point in the vehicles own coordinate system.
Definition: vehicle.cpp:6787
@ TEMP_HEATER
Definition: enums.h:44
static void process_vehicle_items(vehicle &cur_veh, int part)
Definition: map.cpp:4470
float insulation_factor
How much insulation this item provides, either as a container, or as a vehicle base part.
Definition: itype.h:1037
const vpart_info & info() const
Get part definition common to all parts of this type.
bool enabled
Definition: vehicle.h:411
@ VPFLAG_FLUIDTANK
Definition: veh_type.h:73
@ VPFLAG_FREEZER
Definition: veh_type.h:58
@ VPFLAG_FRIDGE
Definition: veh_type.h:57

References vehicle::active_items, submap::contains_vehicle(), vehicle_part::enabled, vehicle::engine_on, vehicle::get_any_parts(), active_item_cache::get_for_processing(), vehicle::get_items(), vehicle::get_parts_including_carried(), vpart_info::has_flag(), vehicle::has_part(), vehicle_part::info(), itype::insulation_factor, item::is_corpse(), item::is_food(), item::is_food_container(), vpart_info::item, vpart_position::mount(), process_map_items(), process_vehicle_items(), TEMP_FREEZER, TEMP_FRIDGE, TEMP_HEATER, TEMP_NORMAL, VPFLAG_CARGO, VPFLAG_FLUIDTANK, VPFLAG_FREEZER, and VPFLAG_FRIDGE.

Referenced by process_items_in_vehicles().

◆ process_items_in_vehicles()

void map::process_items_in_vehicles ( submap current_submap)
private

Definition at line 4627 of file map.cpp.

4628{
4629 // a copy, important if the vehicle list changes because a
4630 // vehicle got destroyed by a bomb (an active item!), this list
4631 // won't change, but veh_in_nonant will change.
4632 std::vector<vehicle *> vehicles;
4633 for( const auto &veh : current_submap.vehicles ) {
4634 vehicles.push_back( veh.get() );
4635 }
4636 for( auto &cur_veh : vehicles ) {
4637 if( !current_submap.contains_vehicle( cur_veh ) ) {
4638 // vehicle not in the vehicle list of the nonant, has been
4639 // destroyed (or moved to another nonant?)
4640 // Can't be sure that it still exists, so skip it
4641 continue;
4642 }
4643
4644 process_items_in_vehicle( *cur_veh, current_submap );
4645 }
4646}
void process_items_in_vehicle(vehicle &cur_veh, submap &current_submap)
Definition: map.cpp:4648

References submap::contains_vehicle(), process_items_in_vehicle(), and submap::vehicles.

Referenced by process_items().

◆ produce_sap()

void map::produce_sap ( const tripoint p,
const time_duration time_since_last_actualize 
)
protected

Produce sap on tapped maple trees.

Parameters
pLocation of tapped tree
time_since_last_actualizeTime since this function has been called the last time.

Definition at line 7243 of file map.cpp.

7244{
7245 if( time_since_last_actualize <= 0_turns ) {
7246 return;
7247 }
7248
7249 if( t_tree_maple_tapped != ter( p ) ) {
7250 return;
7251 }
7252
7253 // Amount of maple sap liters produced per season per tap
7254 static const int maple_sap_per_season = 56;
7255
7256 // How many turns to produce 1 charge (250 ml) of sap?
7257 const time_duration producing_length = 0.75 * calendar::season_length();
7258
7259 const time_duration turns_to_produce = producing_length / ( maple_sap_per_season * 4 );
7260
7261 // How long of this time_since_last_actualize have we been in the producing period (late winter, early spring)?
7262 time_duration time_producing = 0_turns;
7263
7264 if( time_since_last_actualize >= calendar::year_length() ) {
7265 time_producing = producing_length;
7266 } else {
7267 // We are only producing sap on the intersection with the sap producing season.
7268 const time_duration early_spring_end = 0.5f * calendar::season_length();
7269 const time_duration late_winter_start = 3.75f * calendar::season_length();
7270
7271 const time_point last_actualize = calendar::turn - time_since_last_actualize;
7272 const time_duration last_actualize_tof = time_past_new_year( last_actualize );
7273 bool last_producing = (
7274 last_actualize_tof >= late_winter_start ||
7275 last_actualize_tof < early_spring_end
7276 );
7277 const time_duration current_tof = time_past_new_year( calendar::turn );
7278 bool current_producing = (
7279 current_tof >= late_winter_start ||
7280 current_tof < early_spring_end
7281 );
7282
7283 const time_duration non_producing_length = 3.25 * calendar::season_length();
7284
7285 if( last_producing && current_producing ) {
7286 if( time_since_last_actualize < non_producing_length ) {
7287 time_producing = time_since_last_actualize;
7288 } else {
7289 time_producing = time_since_last_actualize - non_producing_length;
7290 }
7291 } else if( !last_producing && !current_producing ) {
7292 if( time_since_last_actualize > non_producing_length ) {
7293 time_producing = time_since_last_actualize - non_producing_length;
7294 }
7295 } else if( last_producing && !current_producing ) {
7296 // We hit the end of early spring
7297 if( last_actualize_tof < early_spring_end ) {
7298 time_producing = early_spring_end - last_actualize_tof;
7299 } else {
7300 time_producing = calendar::year_length() - last_actualize_tof + early_spring_end;
7301 }
7302 } else if( !last_producing && current_producing ) {
7303 // We hit the start of late winter
7304 if( current_tof >= late_winter_start ) {
7305 time_producing = current_tof - late_winter_start;
7306 } else {
7307 time_producing = 0.25f * calendar::season_length() + current_tof;
7308 }
7309 }
7310 }
7311
7312 int new_charges = roll_remainder( time_producing / turns_to_produce );
7313 // Not enough time to produce 1 charge of sap
7314 if( new_charges <= 0 ) {
7315 return;
7316 }
7317
7318 item sap( "maple_sap", calendar::turn );
7319
7320 // Is there a proper container?
7321 auto items = i_at( p );
7322 for( auto &it : items ) {
7323 if( it.is_bucket() || it.is_watertight_container() ) {
7324 const int capacity = it.get_remaining_capacity_for_liquid( sap, true );
7325 if( capacity > 0 ) {
7326 new_charges = std::min( new_charges, capacity );
7327
7328 // The environment might have poisoned the sap with animals passing by, insects, leaves or contaminants in the ground
7329 sap.poison = one_in( 10 ) ? 1 : 0;
7330 sap.charges = new_charges;
7331
7332 it.fill_with( sap );
7333 }
7334 // Only fill up the first container.
7335 break;
7336 }
7337 }
7338}
time_duration time_past_new_year(const time_point &p)
Definition: calendar.h:502
A point in the game time.
Definition: calendar.h:431
ter_id t_tree_maple_tapped
Definition: mapdata.cpp:681
time_duration year_length()
Definition: calendar.cpp:461
time_duration season_length()
Definition: calendar.cpp:466

References item::charges, i_at(), one_in(), item::poison, roll_remainder(), calendar::season_length(), t_tree_maple_tapped, ter(), time_past_new_year(), calendar::turn, and calendar::year_length().

Referenced by actualize().

◆ propagate_field()

void map::propagate_field ( const tripoint center,
const field_type_id type,
int  amount,
int  max_intensity = 0 
)

Definition at line 1941 of file map_field.cpp.

1943{
1944 using gas_blast = std::pair<float, tripoint>;
1945 std::priority_queue<gas_blast, std::vector<gas_blast>, pair_greater_cmp_first> open;
1946 std::set<tripoint> closed;
1947 open.push( { 0.0f, center } );
1948
1949 const bool not_gas = type.obj().phase != GAS;
1950
1951 while( amount > 0 && !open.empty() ) {
1952 if( closed.count( open.top().second ) ) {
1953 open.pop();
1954 continue;
1955 }
1956
1957 // All points with equal gas intensity should propagate at the same time
1958 std::list<gas_blast> gas_front;
1959 gas_front.push_back( open.top() );
1960 const int cur_intensity = get_field_intensity( open.top().second, type );
1961 open.pop();
1962 while( !open.empty() && get_field_intensity( open.top().second, type ) == cur_intensity ) {
1963 if( closed.count( open.top().second ) == 0 ) {
1964 gas_front.push_back( open.top() );
1965 }
1966
1967 open.pop();
1968 }
1969
1970 int increment = std::max<int>( 1, amount / gas_front.size() );
1971
1972 while( !gas_front.empty() ) {
1973 gas_blast gp = random_entry_removed( gas_front );
1974 closed.insert( gp.second );
1975 const int cur_intensity = get_field_intensity( gp.second, type );
1976 if( cur_intensity < max_intensity ) {
1977 const int bonus = std::min( max_intensity - cur_intensity, increment );
1978 mod_field_intensity( gp.second, type, bonus );
1979 amount -= bonus;
1980 } else {
1981 amount--;
1982 }
1983
1984 if( amount <= 0 ) {
1985 return;
1986 }
1987
1988 static const std::array<int, 8> x_offset = {{ -1, 1, 0, 0, 1, -1, -1, 1 }};
1989 static const std::array<int, 8> y_offset = {{ 0, 0, -1, 1, -1, 1, -1, 1 }};
1990 for( size_t i = 0; i < 8; i++ ) {
1991 tripoint pt = gp.second + point( x_offset[ i ], y_offset[ i ] );
1992 if( closed.count( pt ) > 0 ) {
1993 continue;
1994 }
1995
1996 if( impassable( pt ) && ( not_gas || !has_flag( TFLAG_PERMEABLE, pt ) ) ) {
1997 closed.insert( pt );
1998 continue;
1999 }
2000 if( !obstructed_by_vehicle_rotation( gp.second, pt ) ) {
2001 open.push( { static_cast<float>( rl_dist( center, pt ) ), pt } );
2002 }
2003 }
2004 }
2005 }
2006}
@ GAS
Definition: enums.h:175
Greater-than comparison operator; required by the sort interface.
Definition: cata_utility.h:16

References center, GAS, get_field_intensity(), has_flag(), impassable(), mod_field_intensity(), obstructed_by_vehicle_rotation(), open(), random_entry_removed(), rl_dist(), TFLAG_PERMEABLE, and type.

Referenced by computer_session::action_irradiator(), and emit_field().

◆ propagate_suspension_check()

void map::propagate_suspension_check ( const tripoint point)

Checks surrounding tiles for suspension, and has them check for collapse.

!!Should only be called after the tile at this point has been destroyed!!

Definition at line 2943 of file map.cpp.

2944{
2945 for( const tripoint &neighbor : points_in_radius( point, 1 ) ) {
2946 if( neighbor != point && has_flag( TFLAG_SUSPENDED, neighbor ) ) {
2947 collapse_invalid_suspension( neighbor );
2948 }
2949 }
2950}

References collapse_invalid_suspension(), has_flag(), points_in_radius(), and TFLAG_SUSPENDED.

Referenced by bash_ter_success(), collapse_at(), and collapse_invalid_suspension().

◆ put_items_from_loc()

std::vector< item * > map::put_items_from_loc ( const item_group_id loc,
const tripoint p,
const time_point turn = calendar::start_of_cataclysm 
)

Place items from an item group at p.

Places as much items as the item group says. (Most item groups are distributions and will only create one item.)

Parameters
locCurrent location of items
pDestination of items
turnThe birthday that the created items shall have.
Returns
Vector of pointers to placed items (can be empty, but no nulls).

Definition at line 5575 of file mapgen.cpp.

5577{
5578 const auto items = item_group::items_from( loc, turn );
5579 return spawn_items( p, items );
5580}

References item_group::items_from(), spawn_items(), and calendar::turn.

Referenced by add_corpse(), activity_handlers::forage_finish(), mapgen_cavern(), MapExtras::mx_corpses(), MapExtras::mx_grave(), MapExtras::mx_mayhem(), MapExtras::mx_minefield(), and place_items().

◆ rad_scorch()

void map::rad_scorch ( const tripoint p,
const time_duration time_since_last_actualize 
)
protected

Radiation-related plant (and fungus?) death.

Definition at line 7340 of file map.cpp.

7341{
7342 const int rads = get_radiation( p );
7343 if( rads == 0 ) {
7344 return;
7345 }
7346
7347 // TODO: More interesting rad scorch chance - base on season length?
7348 if( !x_in_y( 1.0 * rads * rads * time_since_last_actualize, 91_days ) ) {
7349 return;
7350 }
7351
7352 // First destroy the farmable plants (those are furniture)
7353 // TODO: Rad-resistant mutant plants (that produce radioactive fruit)
7354 const furn_t &fid = furn( p ).obj();
7355 if( fid.has_flag( "PLANT" ) ) {
7356 i_clear( p );
7357 furn_set( p, f_null );
7358 }
7359
7360 const ter_id tid = ter( p );
7361 // TODO: De-hardcode this
7362 static const std::map<ter_id, ter_str_id> dies_into {{
7363 {t_grass, ter_str_id( "t_dirt" )},
7364 {t_tree_young, ter_str_id( "t_dirt" )},
7365 {t_tree_pine, ter_str_id( "t_tree_deadpine" )},
7366 {t_tree_birch, ter_str_id( "t_tree_birch_harvested" )},
7367 {t_tree_willow, ter_str_id( "t_tree_willow_harvested" )},
7368 {t_tree_hickory, ter_str_id( "t_tree_hickory_dead" )},
7369 {t_tree_hickory_harvested, ter_str_id( "t_tree_hickory_dead" )},
7370 }};
7371
7372 const auto iter = dies_into.find( tid );
7373 if( iter != dies_into.end() ) {
7374 ter_set( p, iter->second );
7375 return;
7376 }
7377
7378 const ter_t &tr = tid.obj();
7379 if( tr.has_flag( "SHRUB" ) ) {
7380 ter_set( p, t_dirt );
7381 } else if( tr.has_flag( "TREE" ) ) {
7382 ter_set( p, ter_str_id( "t_tree_dead" ) );
7383 }
7384}
int get_radiation(const tripoint &p) const
Definition: map.cpp:4023
ter_id t_tree_hickory_harvested
Definition: mapdata.cpp:682
ter_id t_tree_willow
Definition: mapdata.cpp:681
ter_id t_tree_birch
Definition: mapdata.cpp:681
ter_id t_tree_pine
Definition: mapdata.cpp:681
ter_id t_tree_young
Definition: mapdata.cpp:677
ter_id t_tree_hickory
Definition: mapdata.cpp:682
string_id< ter_t > ter_str_id
Definition: mapdata.h:24

References f_null, furn(), furn_set(), get_radiation(), map_data_common_t::has_flag(), i_clear(), int_id< T >::obj(), t_dirt, t_grass, t_tree_birch, t_tree_hickory, t_tree_hickory_harvested, t_tree_pine, t_tree_willow, t_tree_young, ter(), ter_set(), and x_in_y().

Referenced by actualize().

◆ random_outdoor_tile()

point map::random_outdoor_tile ( )

Definition at line 2730 of file map.cpp.

2731{
2732 std::vector<point> options;
2733 for( const tripoint &p : points_on_zlevel() ) {
2734 if( is_outside( p.xy() ) ) {
2735 options.push_back( p.xy() );
2736 }
2737 }
2739}
std::string options()
Definition: path_info.cpp:238

References is_outside(), PATH_INFO::options(), point_north_west, points_on_zlevel(), and random_entry().

◆ ranged_target_size()

double map::ranged_target_size ( const tripoint p) const

Size of map objects at p for purposes of ranged combat.

Size is in percentage of tile: if 1.0, all attacks going through tile should hit map objects on it, if 0.0 there is nothing to be hit (air/water).

Definition at line 1955 of file map.cpp.

1956{
1957 if( impassable( p ) ) {
1958 return 1.0;
1959 }
1960
1961 if( !has_floor( p ) ) {
1962 return 0.0;
1963 }
1964
1965 // TODO: Handle cases like shrubs, trees, furniture, sandbags...
1966 return 0.1;
1967}

References has_floor(), and impassable().

Referenced by projectile_attack().

◆ reachable_flood_steps()

void map::reachable_flood_steps ( std::vector< tripoint > &  reachable_pts,
const tripoint f,
int  range,
int  cost_min,
int  cost_max 
) const

Populates a vector of points that are reachable within a number of steps from a point.

It could be generalized to take advantage of z levels, but would need some additional code to detect whether a valid transition was on a tile.

Does the following:

  1. Checks if a point is reachable using a flood fill and if it is, adds it to a vector.

Definition at line 6284 of file map.cpp.

6286{
6287 struct pq_item {
6288 int dist;
6289 int ndx;
6290 };
6291 struct pq_item_comp {
6292 bool operator()( const pq_item &left, const pq_item &right ) {
6293 return left.dist > right.dist;
6294 }
6295 };
6296 using PQ_type = std::priority_queue< pq_item, std::vector<pq_item>, pq_item_comp>;
6297
6298 // temp buffer for grid
6299 const int grid_dim = range * 2 + 1;
6300 // init to -1 as "not visited yet"
6301 std::vector< int > t_grid( static_cast<size_t>( grid_dim * grid_dim ), -1 );
6302 const tripoint origin_offset = {range, range, 0};
6303 const int initial_visit_distance = range * range; // Large unreachable value
6304
6305 // Fill positions that are visitable with initial_visit_distance
6306 for( const tripoint &p : points_in_radius( f, range ) ) {
6307 const tripoint tp = { p.xy(), f.z };
6308 const int tp_cost = move_cost( tp );
6309 // rejection conditions
6310 if( tp_cost < cost_min || tp_cost > cost_max || !has_floor_or_support( tp ) ) {
6311 continue;
6312 }
6313 // set initial cost for grid point
6314 tripoint origin_relative = tp - f;
6315 origin_relative += origin_offset;
6316 int ndx = origin_relative.x + origin_relative.y * grid_dim;
6317 t_grid[ ndx ] = initial_visit_distance;
6318 }
6319
6320 auto gen_neighbors = []( const pq_item & elem, int grid_dim, pq_item * neighbors ) {
6321 // Up to 8 neighbors
6322 int new_cost = elem.dist + 1;
6323 // *INDENT-OFF*
6324 int ox[8] = {
6325 -1, 0, 1,
6326 -1, 1,
6327 -1, 0, 1
6328 };
6329 int oy[8] = {
6330 -1, -1, -1,
6331 0, 0,
6332 1, 1, 1
6333 };
6334 // *INDENT-ON*
6335
6336 point e( elem.ndx % grid_dim, elem.ndx / grid_dim );
6337 for( int i = 0; i < 8; ++i ) {
6338 point n( e + point( ox[i], oy[i] ) );
6339
6340 int ndx = n.x + n.y * grid_dim;
6341 neighbors[i] = { new_cost, ndx };
6342 }
6343 };
6344
6345 PQ_type pq( pq_item_comp{} );
6346 pq_item first_item{ 0, range + range * grid_dim };
6347 pq.push( first_item );
6348 pq_item neighbor_elems[8];
6349
6350 while( !pq.empty() ) {
6351 const pq_item item = pq.top();
6352 pq.pop();
6353
6354 if( t_grid[ item.ndx ] == initial_visit_distance ) {
6355 t_grid[ item.ndx ] = item.dist;
6356 if( item.dist + 1 < range ) {
6357 gen_neighbors( item, grid_dim, neighbor_elems );
6358 for( pq_item neighbor_elem : neighbor_elems ) {
6359 pq.push( neighbor_elem );
6360 }
6361 }
6362 }
6363 }
6364 std::vector<char> o_grid( static_cast<size_t>( grid_dim * grid_dim ), 0 );
6365 for( int y = 0, ndx = 0; y < grid_dim; ++y ) {
6366 for( int x = 0; x < grid_dim; ++x, ++ndx ) {
6367 if( t_grid[ ndx ] != -1 && t_grid[ ndx ] < initial_visit_distance ) {
6368 // set self and neighbors to 1
6369 for( int dy = -1; dy <= 1; ++dy ) {
6370 for( int dx = -1; dx <= 1; ++dx ) {
6371 int tx = dx + x;
6372 int ty = dy + y;
6373
6374 if( tx >= 0 && tx < grid_dim && ty >= 0 && ty < grid_dim ) {
6375 o_grid[ tx + ty * grid_dim ] = 1;
6376 }
6377 }
6378 }
6379 }
6380 }
6381 }
6382
6383 // Now go over again to pull out all of the reachable points
6384 for( int y = 0, ndx = 0; y < grid_dim; ++y ) {
6385 for( int x = 0; x < grid_dim; ++x, ++ndx ) {
6386 if( o_grid[ ndx ] ) {
6387 tripoint t = f - origin_offset + tripoint{ x, y, 0 };
6388 reachable_pts.push_back( t );
6389 }
6390 }
6391 }
6392}

References has_floor_or_support(), left, move_cost(), points_in_radius(), right, point::x, tripoint::x, tripoint::xy(), point::y, tripoint::y, and tripoint::z.

Referenced by inventory::form_from_map(), and use_charges().

◆ register_vehicle_zone()

void map::register_vehicle_zone ( vehicle veh,
int  zlev 
)

Definition at line 957 of file map.cpp.

958{
959 auto &ch = get_cache( zlev );
960 ch.zone_vehicles.insert( veh );
961}

References get_cache().

Referenced by zone_manager::create_vehicle_loot_zone(), and zone_manager::revert_vzones().

◆ remove_field()

void map::remove_field ( const tripoint p,
const field_type_id field_to_remove 
)

Remove field entry at xy, ignored if the field entry is not present.

Definition at line 5453 of file map.cpp.

5454{
5455 if( !inbounds( p ) ) {
5456 return;
5457 }
5458
5459 point l;
5460 submap *const current_submap = get_submap_at( p, l );
5461
5462 if( current_submap->get_field( l ).remove_field( field_to_remove ) ) {
5463 // Only adjust the count if the field actually existed.
5464 if( !--current_submap->field_count ) {
5465 get_cache( p.z ).field_cache.set( static_cast<size_t>( p.x / SEEX + ( (
5466 p.y / SEEX ) * MAPSIZE ) ) );
5467 }
5468 const auto &fdata = field_to_remove.obj();
5469 if( fdata.dirty_transparency_cache || !fdata.is_transparent() ) {
5472 }
5473 if( fdata.is_dangerous() ) {
5475 }
5476 }
5477}

References level_cache::field_cache, submap::field_count, get_cache(), submap::get_field(), get_submap_at(), inbounds(), MAPSIZE, int_id< T >::obj(), field::remove_field(), SEEX, set_pathfinding_cache_dirty(), set_seen_cache_dirty(), set_transparency_cache_dirty(), tripoint::x, tripoint::y, and tripoint::z.

Referenced by computer_session::action_deactivate_shock_vent(), bash_field(), editmap::edit_fld(), iexamine::fireplace(), game::grabbed_furn_move(), MapExtras::mx_house_spider(), MapExtras::mx_spider(), game::process_artifact(), set_field_intensity(), shoot(), smash(), and game::walk_move().

◆ remove_rotten_items()

template<typename Container >
void map::remove_rotten_items ( Container &  items,
const tripoint p 
)
protected

Go through the list of items, update their rotten status and remove items that have rotten away completely.

Parameters
itemsitems to remove
pThe point on this map where the items are, used for rot calculation.

Definition at line 7089 of file map.cpp.

7090{
7091 for( auto it = items.begin(); it != items.end(); ) {
7092 if( it->has_rotten_away( pnt ) ) {
7093 if( it->is_comestible() ) {
7094 rotten_item_spawn( *it, pnt );
7095 }
7096 it = i_rem( pnt, it );
7097 } else {
7098 ++it;
7099 }
7100 }
7101}

References i_rem(), and rotten_item_spawn().

Referenced by actualize().

◆ remove_submap_camp()

void map::remove_submap_camp ( const tripoint p)

Definition at line 5568 of file map.cpp.

5569{
5570 get_submap_at( p )->camp.reset();
5571}

References submap::camp, and get_submap_at().

Referenced by basecamp::abandon_camp(), and game::validate_camps().

◆ remove_trap()

void map::remove_trap ( const tripoint p)

Definition at line 5261 of file map.cpp.

5262{
5263 if( !inbounds( p ) ) {
5264 return;
5265 }
5266
5267 point l;
5268 submap *const current_submap = get_submap_at( p, l );
5269
5270 trap_id tid = current_submap->get_trap( l );
5271 if( tid != tr_null ) {
5272 if( g != nullptr && this == &get_map() ) {
5273 g->u.add_known_trap( p, tr_null.obj() );
5274 }
5275
5276 current_submap->set_trap( l, tr_null );
5277 auto &traps = traplocs[tid.to_i()];
5278 const auto iter = std::find( traps.begin(), traps.end(), p );
5279 if( iter != traps.end() ) {
5280 traps.erase( iter );
5281 }
5282 }
5283}
void set_trap(const point &p, trap_id trap)
Definition: submap.h:77
FMT_CONSTEXPR bool find(Ptr first, Ptr last, T value, Ptr &out)

References detail::find(), g, get_map(), get_submap_at(), submap::get_trap(), inbounds(), int_id< T >::obj(), submap::set_trap(), int_id< T >::to_i(), tr_null, and traplocs.

Referenced by complete_construction(), vehicle::handle_trap(), trapfunc::map_regen(), mremove_trap(), trap::on_disarmed(), game::process_artifact(), and trap_set().

◆ reset_vehicle_cache()

void map::reset_vehicle_cache ( )

Definition at line 254 of file map.cpp.

255{
258
259 // Cache all vehicles
260 const int zmin = zlevels ? -OVERMAP_DEPTH : abs_sub.z;
261 const int zmax = zlevels ? OVERMAP_HEIGHT : abs_sub.z;
262 for( int zlev = zmin; zlev <= zmax; zlev++ ) {
263 auto &ch = get_cache( zlev );
264 for( const auto &elem : ch.vehicle_list ) {
265 elem->adjust_zlevel( 0, tripoint_zero );
266 add_vehicle_to_cache( elem );
267 }
268 }
269}
void clear_vehicle_cache()
Definition: map.cpp:313

References abs_sub, add_vehicle_to_cache(), clear_vehicle_cache(), get_cache(), last_full_vehicle_list_dirty, OVERMAP_DEPTH, OVERMAP_HEIGHT, tripoint_zero, tripoint::z, and zlevels.

Referenced by veh_interact::complete_vehicle(), detach_vehicle(), editmap::draw_main_ui_overlay(), load(), loadn(), editmap::mapgen_preview(), editmap::mapgen_veh_destroy(), rotate(), shift(), and vehicle::use_bike_rack().

◆ restock_fruits()

void map::restock_fruits ( const tripoint p,
const time_duration time_since_last_actualize 
)
protected

Try to grow fruits on static plants (not planted by the player)

Parameters
pPlace to restock
time_since_last_actualizeTime since this function has been called the last time.

Definition at line 7229 of file map.cpp.

7230{
7231 const auto &ter = this->ter( p ).obj();
7232 if( !ter.has_flag( TFLAG_HARVESTED ) ) {
7233 return; // Already harvestable. Do nothing.
7234 }
7235 // Make it harvestable again if the last actualization was during a different season or year.
7236 const time_point last_touched = calendar::turn - time_since_last_actualize;
7237 if( season_of_year( calendar::turn ) != season_of_year( last_touched ) ||
7238 time_since_last_actualize >= calendar::season_length() ) {
7239 ter_set( p, ter.transforms_into );
7240 }
7241}
season_type season_of_year(const time_point &p)
Definition: calendar.cpp:547

References int_id< T >::obj(), calendar::season_length(), season_of_year(), ter(), ter_set(), TFLAG_HARVESTED, and calendar::turn.

Referenced by actualize(), and saven().

◆ rotate()

void map::rotate ( int  turns,
bool  setpos_safe = false 
)

Rotates this map, and all of its contents, by the specified multiple of 90 degrees.

Parameters
turnsHow many 90-degree turns to rotate the map.

Definition at line 5802 of file mapgen.cpp.

5803{
5804
5805 //Handle anything outside the 1-3 range gracefully; rotate(0) is a no-op.
5806 turns = turns % 4;
5807 if( turns == 0 ) {
5808 return;
5809 }
5810
5811 real_coords rc;
5812 const tripoint &abs_sub = get_abs_sub();
5813 rc.fromabs( point( abs_sub.x * SEEX, abs_sub.y * SEEY ) );
5814
5815 // TODO: This radius can be smaller - how small?
5816 const int radius = HALF_MAPSIZE + 3;
5817 // uses submap coordinates
5818 // TODO: fix point types
5819 const std::vector<shared_ptr_fast<npc>> npcs =
5821 for( const shared_ptr_fast<npc> &i : npcs ) {
5822 npc &np = *i;
5823 const tripoint sq = np.global_square_location();
5824 const point local_sq = getlocal( sq ).xy();
5825
5826 real_coords np_rc;
5827 np_rc.fromabs( sq.xy() );
5828 // Note: We are rotating the entire overmap square (2x2 of submaps)
5829 if( np_rc.om_pos != rc.om_pos || sq.z != abs_sub.z ) {
5830 continue;
5831 }
5832
5833 // OK, this is ugly: we remove the NPC from the whole map
5834 // Then we place it back from scratch
5835 // It could be rewritten to utilize the fact that rotation shouldn't cross overmaps
5836
5837 point old( np_rc.sub_pos );
5838 if( np_rc.om_sub.x % 2 != 0 ) {
5839 old.x += SEEX;
5840 }
5841 if( np_rc.om_sub.y % 2 != 0 ) {
5842 old.y += SEEY;
5843 }
5844
5845 const point new_pos = old .rotate( turns, { SEEX * 2, SEEY * 2 } );
5846 if( setpos_safe ) {
5847 // setpos can't be used during mapgen, but spawn_at_precise clips position
5848 // to be between 0-11,0-11 and teleports NPCs when used inside of update_mapgen
5849 // calls
5850 const tripoint new_global_sq = sq - local_sq + new_pos;
5851 np.setpos( get_map().getlocal( new_global_sq ) );
5852 } else {
5853 // OK, this is ugly: we remove the NPC from the whole map
5854 // Then we place it back from scratch
5855 // It could be rewritten to utilize the fact that rotation shouldn't cross overmaps
5857 np.spawn_at_precise( { abs_sub.xy() }, { new_pos, abs_sub.z } );
5859 }
5860 }
5861
5864
5865 // Move the submaps around.
5866 if( turns == 2 ) {
5869 } else {
5870 point p;
5871 submap tmp;
5872
5874
5875 for( int k = 0; k < 4; ++k ) {
5876 p = p.rotate( turns, { 2, 2 } );
5878 }
5879 }
5880
5881 // Then rotate them and recalculate vehicle positions.
5882 for( int j = 0; j < 2; ++j ) {
5883 for( int i = 0; i < 2; ++i ) {
5884 point p( i, j );
5885 auto sm = get_submap_at_grid( p );
5886
5887 sm->rotate( turns );
5888
5889 for( auto &veh : sm->vehicles ) {
5890 veh->sm_pos = tripoint( p, abs_sub.z );
5891 }
5892
5894 }
5895 }
5897
5898 // rotate zones
5900 mgr.rotate_zones( *this, turns );
5901}
shared_ptr_fast< npc > npc_ptr
Definition: basecamp.h:46
character_id getID() const
Definition: character.cpp:477
void clear_vehicle_list(int zlev)
Definition: map.cpp:331
void spawn_at_precise(const point &submap_offset, const tripoint &square)
As spawn_at, but also sets position within the submap.
Definition: npc.cpp:729
void setpos(const tripoint &pos) override
Note: this places NPC on a given position in CURRENT MAP coordinates.
Definition: npc.cpp:681
tripoint global_square_location() const override
Global position, expressed in map square coordinate system (the most detailed coordinate system),...
Definition: npc.cpp:739
std::vector< shared_ptr_fast< npc > > get_npcs_near(const tripoint_abs_sm &p, int radius)
Get all npcs in a area with given radius around given central point.
shared_ptr_fast< npc > remove_npc(const character_id &id)
Find npc by id and if found, erase it from the npc list and return it ( or return nullptr if not foun...
void rotate_zones(map &target_map, int turns)
Definition: clzones.cpp:1052
coords::coord_point< tripoint, coords::origin::abs, coords::sm > tripoint_abs_sm
Definition: coordinates.h:490
static constexpr int HALF_MAPSIZE
void swap(colony< element_type, element_allocator_type, element_skipfield_type > &a, colony< element_type, element_allocator_type, element_skipfield_type > &b) COLONY_NOEXCEPT_SWAP(element_allocator_type)
Swaps colony A's contents with that of colony B.
Definition: colony.h:3496
point rotate(int turns, const point &dim={ 1, 1 }) const
Rotate point clockwise.
Definition: point.h:89
point om_sub
Definition: coordinates.h:638
void fromabs(const point &abs)
Definition: coordinates.h:646
point om_pos
Definition: coordinates.h:637
point sub_pos
Definition: coordinates.h:635

References abs_sub, clear_vehicle_cache(), clear_vehicle_list(), real_coords::fromabs(), get_abs_sub(), zone_manager::get_manager(), get_map(), overmapbuffer::get_npcs_near(), get_submap_at_grid(), Character::getID(), getlocal(), npc::global_square_location(), HALF_MAPSIZE, overmapbuffer::insert_npc(), real_coords::om_pos, real_coords::om_sub, overmap_buffer, point_east, point_south, point_south_east, point_zero, overmapbuffer::remove_npc(), reset_vehicle_cache(), point::rotate(), zone_manager::rotate_zones(), SEEX, SEEY, npc::setpos(), coords::sm, npc::spawn_at_precise(), real_coords::sub_pos, cata::swap(), update_vehicle_list(), point::x, tripoint::x, tripoint::xy(), point::y, tripoint::y, and tripoint::z.

Referenced by draw_connections(), draw_lab(), draw_office_tower(), draw_triffid(), mapgen_function_json::generate(), mapgen_ants_curved(), mapgen_ants_straight(), mapgen_ants_tee(), mapgen_forest_trail_curved(), mapgen_forest_trail_straight(), mapgen_forest_trail_tee(), mapgen_highway(), mapgen_parking_lot(), editmap::mapgen_preview(), mapgen_railroad(), mapgen_railroad_bridge(), mapgen_river_curved(), mapgen_river_curved_not(), mapgen_river_straight(), mapgen_road(), mapgen_rotate(), mapgen_sewer_curved(), mapgen_sewer_straight(), mapgen_sewer_tee(), mapgen_subway(), and update_mapgen_function_json::update_map().

◆ rotten_item_spawn()

void map::rotten_item_spawn ( const item item,
const tripoint p 
)

Checks to see if the item that is rotting away generates a creature when it does.

Parameters
itemitem that is spawning creatures
pThe point on this map where the item is and creature will be

Definition at line 7103 of file map.cpp.

7104{
7105 if( g->critter_at( pnt ) != nullptr ) {
7106 return;
7107 }
7108 const auto &comest = item.get_comestible();
7109 mongroup_id mgroup = comest->rot_spawn;
7110 if( !mgroup ) {
7111 return;
7112 }
7113 const int chance = static_cast<int>( comest->rot_spawn_chance *
7114 get_option<float>( "CARRION_SPAWNRATE" ) );
7115 if( rng( 0, 100 ) < chance ) {
7117 add_spawn( spawn_details.name, 1, pnt, false );
7118 if( g->u.sees( pnt ) ) {
7119 if( item.is_seed() ) {
7120 add_msg( m_warning, _( "Something has crawled out of the %s plants!" ), item.get_plant_name() );
7121 } else {
7122 add_msg( m_warning, _( "Something has crawled out of the %s!" ), item.tname() );
7123 }
7124 }
7125 }
7126}
const cata::value_ptr< islot_comestible > & get_comestible() const
Definition: item.cpp:9972
std::string get_plant_name() const
The name of the plant as it appears in the various informational menus.
Definition: item.cpp:9641
bool is_seed() const
Whether this is actually a seed, the seed functions won't be of much use for non-seeds.
Definition: item.cpp:9622

References _, add_msg(), add_spawn(), g, item::get_comestible(), item::get_plant_name(), MonsterGroupManager::GetResultFromGroup(), item::is_seed(), m_warning, MonsterGroupResult::name, rng(), and item::tname().

Referenced by grow_plant(), and remove_rotten_items().

◆ route()

std::vector< tripoint > map::route ( const tripoint f,
const tripoint t,
const pathfinding_settings settings,
const std::set< tripoint > &  pre_closed = {{ }} 
) const

Calculate the best path using A*.

Parameters
fThe source location from which to path.
tThe destination to which to path.
settingsStructure describing pathfinding parameters.
pre_closedNever path through those points. They can still be the source or the destination.

Definition at line 194 of file pathfinding.cpp.

197{
198 /* TODO: If the origin or destination is out of bound, figure out the closest
199 * in-bounds point and go to that, then to the real origin/destination.
200 */
201 std::vector<tripoint> ret;
202
203 if( f == t || !inbounds( f ) ) {
204 return ret;
205 }
206
207 if( !inbounds( t ) ) {
208 tripoint clipped = t;
209 clip_to_bounds( clipped );
210 return route( f, clipped, settings, pre_closed );
211 }
212 // First, check for a simple straight line on flat ground
213 // Except when the line contains a pre-closed tile - we need to do regular pathing then
214 static const auto non_normal = PF_SLOW | PF_WALL | PF_VEHICLE | PF_TRAP | PF_SHARP;
215 if( f.z == t.z ) {
216 const auto line_path = line_to( f, t );
217 const auto &pf_cache = get_pathfinding_cache_ref( f.z );
218 // Check all points for any special case (including just hard terrain)
219 if( !( pf_cache.special[f.x][f.y] & non_normal ) &&
220 std::all_of( line_path.begin(), line_path.end(), [&pf_cache]( const tripoint & p ) {
221 return !( pf_cache.special[p.x][p.y] & non_normal );
222 } ) ) {
223 const std::set<tripoint> sorted_line( line_path.begin(), line_path.end() );
224
225 if( is_disjoint( sorted_line, pre_closed ) ) {
226 return line_path;
227 }
228 }
229 }
230
231 // If expected path length is greater than max distance, allow only line path, like above
232 if( rl_dist( f, t ) > settings.max_dist ) {
233 return ret;
234 }
235
236 int max_length = settings.max_length;
237 int bash = settings.bash_strength;
238 int climb_cost = settings.climb_cost;
239 bool doors = settings.allow_open_doors;
240 bool trapavoid = settings.avoid_traps;
241 bool roughavoid = settings.avoid_rough_terrain;
242 bool sharpavoid = settings.avoid_sharp;
243
244 const int pad = 16; // Should be much bigger - low value makes pathfinders dumb!
245 int minx = std::min( f.x, t.x ) - pad;
246 int miny = std::min( f.y, t.y ) - pad;
247 // TODO: Make this way bigger
248 int minz = std::min( f.z, t.z );
249 int maxx = std::max( f.x, t.x ) + pad;
250 int maxy = std::max( f.y, t.y ) + pad;
251 // Same TODO: as above
252 int maxz = std::max( f.z, t.z );
253 clip_to_bounds( minx, miny, minz );
254 clip_to_bounds( maxx, maxy, maxz );
255
256 pathfinder pf( point( minx, miny ), point( maxx, maxy ) );
257 // Make NPCs not want to path through player
258 // But don't make player pathing stop working
259 for( const auto &p : pre_closed ) {
260 if( p.x >= minx && p.x < maxx && p.y >= miny && p.y < maxy ) {
261 pf.close_point( p );
262 }
263 }
264
265 // Start and end must not be closed
266 pf.unclose_point( f );
267 pf.unclose_point( t );
268 pf.add_point( 0, 0, f, f );
269
270 bool done = false;
271
272 do {
273 auto cur = pf.get_next();
274
275 const int parent_index = flat_index( cur );
276 auto &layer = pf.get_layer( cur.z );
277 auto &cur_state = layer.state[parent_index];
278 if( cur_state == ASL_CLOSED ) {
279 continue;
280 }
281
282 if( layer.gscore[parent_index] > max_length ) {
283 // Shortest path would be too long, return empty vector
284 return std::vector<tripoint>();
285 }
286
287 if( cur == t ) {
288 done = true;
289 break;
290 }
291
292 cur_state = ASL_CLOSED;
293
294 const auto &pf_cache = get_pathfinding_cache_ref( cur.z );
295 const auto cur_special = pf_cache.special[cur.x][cur.y];
296
297 int cur_part;
298 const vehicle *cur_veh = veh_at_internal( cur, cur_part );
299
300 // 7 3 5
301 // 1 . 2
302 // 6 4 8
303 constexpr std::array<int, 8> x_offset{{ -1, 1, 0, 0, 1, -1, -1, 1 }};
304 constexpr std::array<int, 8> y_offset{{ 0, 0, -1, 1, -1, 1, -1, 1 }};
305 for( size_t i = 0; i < 8; i++ ) {
306 const tripoint p( cur.x + x_offset[i], cur.y + y_offset[i], cur.z );
307 const int index = flat_index( p );
308
309 // TODO: Remove this and instead have sentinels at the edges
310 if( p.x < minx || p.x >= maxx || p.y < miny || p.y >= maxy ) {
311 continue;
312 }
313
314 if( layer.state[index] == ASL_CLOSED ) {
315 continue;
316 }
317
318 int part = -1;
319 const vehicle *veh = veh_at_internal( p, part );
320 if( cur_veh &&
321 !cur_veh->allowed_move( cur_veh->tripoint_to_mount( cur ), cur_veh->tripoint_to_mount( p ) ) ) {
322 //Trying to squeeze through a vehicle hole, skip this movement but don't close the tile as other paths may lead to it
323 continue;
324 }
325
326 if( veh && veh != cur_veh &&
327 !veh->allowed_move( veh->tripoint_to_mount( cur ), veh->tripoint_to_mount( p ) ) ) {
328 //Same as above but moving into rather than out of a vehicle
329 continue;
330 }
331
332 // Penalize for diagonals or the path will look "unnatural"
333 int newg = layer.gscore[parent_index] + ( ( cur.x != p.x && cur.y != p.y ) ? 1 : 0 );
334
335 const auto p_special = pf_cache.special[p.x][p.y];
336 // TODO: De-uglify, de-huge-n
337 if( !( p_special & non_normal ) ) {
338 // Boring flat dirt - the most common case above the ground
339 newg += 2;
340 } else {
341 if( roughavoid ) {
342 layer.state[index] = ASL_CLOSED; // Close all rough terrain tiles
343 continue;
344 }
345
346 const maptile &tile = maptile_at_internal( p );
347 const auto &terrain = tile.get_ter_t();
348 const auto &furniture = tile.get_furn_t();
349
350 const int cost = move_cost_internal( furniture, terrain, veh, part );
351 // Don't calculate bash rating unless we intend to actually use it
352 const int rating = ( bash == 0 || cost != 0 ) ? -1 :
353 bash_rating_internal( bash, furniture, terrain, false, veh, part );
354
355 if( cost == 0 && rating <= 0 && ( !doors || !terrain.open || !furniture.open ) && veh == nullptr &&
356 climb_cost <= 0 ) {
357 layer.state[index] = ASL_CLOSED; // Close it so that next time we won't try to calculate costs
358 continue;
359 }
360
361 newg += cost;
362 if( cost == 0 ) {
363 if( climb_cost > 0 && p_special & PF_CLIMBABLE ) {
364 // Climbing fences
365 newg += climb_cost;
366 } else if( doors && ( terrain.open || furniture.open ) &&
367 ( !terrain.has_flag( "OPENCLOSE_INSIDE" ) || !furniture.has_flag( "OPENCLOSE_INSIDE" ) ||
368 !is_outside( cur ) ) ) {
369 // Only try to open INSIDE doors from the inside
370 // To open and then move onto the tile
371 newg += 4;
372 } else if( veh != nullptr ) {
373 const auto vpobst = vpart_position( const_cast<vehicle &>( *veh ), part ).obstacle_at_part();
374 part = vpobst ? vpobst->part_index() : -1;
375 int dummy = -1;
376 if( doors && veh->part_flag( part, VPFLAG_OPENABLE ) &&
377 ( !veh->part_flag( part, "OPENCLOSE_INSIDE" ) ||
378 veh_at_internal( cur, dummy ) == veh ) ) {
379 // Handle car doors, but don't try to path through curtains
380 newg += 10; // One turn to open, 4 to move there
381 } else if( part >= 0 && bash > 0 ) {
382 // Car obstacle that isn't a door
383 // TODO: Account for armor
384 int hp = veh->cpart( part ).hp();
385 if( hp / 20 > bash ) {
386 // Threshold damage thing means we just can't bash this down
387 layer.state[index] = ASL_CLOSED;
388 continue;
389 } else if( hp / 10 > bash ) {
390 // Threshold damage thing means we will fail to deal damage pretty often
391 hp *= 2;
392 }
393
394 newg += 2 * hp / bash + 8 + 4;
395 } else if( part >= 0 ) {
396 if( !doors || !veh->part_flag( part, VPFLAG_OPENABLE ) ) {
397 // Won't be openable, don't try from other sides
398 layer.state[index] = ASL_CLOSED;
399 }
400
401 continue;
402 }
403 } else if( rating > 1 ) {
404 // Expected number of turns to bash it down, 1 turn to move there
405 // and 5 turns of penalty not to trash everything just because we can
406 newg += ( 20 / rating ) + 2 + 10;
407 } else if( rating == 1 ) {
408 // Desperate measures, avoid whenever possible
409 newg += 500;
410 } else {
411 // Unbashable and unopenable from here
412 if( !doors || !terrain.open || !furniture.open ) {
413 // Or anywhere else for that matter
414 layer.state[index] = ASL_CLOSED;
415 }
416
417 continue;
418 }
419 }
420
421 if( trapavoid && p_special & PF_TRAP ) {
422 const auto &ter_trp = terrain.trap.obj();
423 const auto &trp = ter_trp.is_benign() ? tile.get_trap_t() : ter_trp;
424 if( !trp.is_benign() ) {
425 // For now make them detect all traps
426 if( has_zlevels() && terrain.has_flag( TFLAG_NO_FLOOR ) ) {
427 // Special case - ledge in z-levels
428 // Warning: really expensive, needs a cache
429 if( valid_move( p, tripoint( p.xy(), p.z - 1 ), false, true ) ) {
430 tripoint below( p.xy(), p.z - 1 );
431 if( !has_flag( TFLAG_NO_FLOOR, below ) ) {
432 // Otherwise this would have been a huge fall
433 auto &layer = pf.get_layer( p.z - 1 );
434 // From cur, not p, because we won't be walking on air
435 pf.add_point( layer.gscore[parent_index] + 10,
436 layer.score[parent_index] + 10 + 2 * rl_dist( below, t ),
437 cur, below );
438 }
439
440 // Close p, because we won't be walking on it
441 layer.state[index] = ASL_CLOSED;
442 continue;
443 }
444 } else if( trapavoid ) {
445 // Otherwise it's walkable
446 newg += 500;
447 }
448 }
449 }
450
451 if( sharpavoid && p_special & PF_SHARP ) {
452 layer.state[index] = ASL_CLOSED; // Avoid sharp things
453 }
454
455 }
456
457 // If not visited, add as open
458 // If visited, add it only if we can do so with better score
459 if( layer.state[index] == ASL_NONE || newg < layer.gscore[index] ) {
460 pf.add_point( newg, newg + 2 * rl_dist( p, t ), cur, p );
461 }
462 }
463
464 if( !has_zlevels() || !( cur_special & PF_UPDOWN ) || !settings.allow_climb_stairs ) {
465 // The part below is only for z-level pathing
466 continue;
467 }
468
469 const maptile &parent_tile = maptile_at_internal( cur );
470 const auto &parent_terrain = parent_tile.get_ter_t();
471 if( settings.allow_climb_stairs && cur.z > minz && parent_terrain.has_flag( TFLAG_GOES_DOWN ) ) {
472 tripoint dest( cur.xy(), cur.z - 1 );
473 if( vertical_move_destination<TFLAG_GOES_UP>( *this, dest ) ) {
474 auto &layer = pf.get_layer( dest.z );
475 pf.add_point( layer.gscore[parent_index] + 2,
476 layer.score[parent_index] + 2 * rl_dist( dest, t ),
477 cur, dest );
478 }
479 }
480 if( settings.allow_climb_stairs && cur.z < maxz && parent_terrain.has_flag( TFLAG_GOES_UP ) ) {
481 tripoint dest( cur.xy(), cur.z + 1 );
482 if( vertical_move_destination<TFLAG_GOES_DOWN>( *this, dest ) ) {
483 auto &layer = pf.get_layer( dest.z );
484 pf.add_point( layer.gscore[parent_index] + 2,
485 layer.score[parent_index] + 2 * rl_dist( dest, t ),
486 cur, dest );
487 }
488 }
489 if( cur.z < maxz && parent_terrain.has_flag( TFLAG_RAMP ) &&
490 valid_move( cur, tripoint( cur.xy(), cur.z + 1 ), false, true ) ) {
491 auto &layer = pf.get_layer( cur.z + 1 );
492 for( size_t it = 0; it < 8; it++ ) {
493 const tripoint above( cur.x + x_offset[it], cur.y + y_offset[it], cur.z + 1 );
494 pf.add_point( layer.gscore[parent_index] + 4,
495 layer.score[parent_index] + 4 + 2 * rl_dist( above, t ),
496 cur, above );
497 }
498 }
499 if( cur.z < maxz && parent_terrain.has_flag( TFLAG_RAMP_UP ) &&
500 valid_move( cur, tripoint( cur.xy(), cur.z + 1 ), false, true, true ) ) {
501 auto &layer = pf.get_layer( cur.z + 1 );
502 for( size_t it = 0; it < 8; it++ ) {
503 const tripoint above( cur.x + x_offset[it], cur.y + y_offset[it], cur.z + 1 );
504 pf.add_point( layer.gscore[parent_index] + 4,
505 layer.score[parent_index] + 4 + 2 * rl_dist( above, t ),
506 cur, above );
507 }
508 }
509 if( cur.z > minz && parent_terrain.has_flag( TFLAG_RAMP_DOWN ) &&
510 valid_move( cur, tripoint( cur.xy(), cur.z - 1 ), false, true, true ) ) {
511 auto &layer = pf.get_layer( cur.z - 1 );
512 for( size_t it = 0; it < 8; it++ ) {
513 const tripoint below( cur.x + x_offset[it], cur.y + y_offset[it], cur.z - 1 );
514 pf.add_point( layer.gscore[parent_index] + 4,
515 layer.score[parent_index] + 4 + 2 * rl_dist( below, t ),
516 cur, below );
517 }
518 }
519
520 } while( !done && !pf.empty() );
521
522 if( done ) {
523 ret.reserve( rl_dist( f, t ) * 2 );
524 tripoint cur = t;
525 // Just to limit max distance, in case something weird happens
526 for( int fdist = max_length; fdist != 0; fdist-- ) {
527 const int cur_index = flat_index( cur );
528 const auto &layer = pf.get_layer( cur.z );
529 const tripoint &par = layer.parent[cur_index];
530 if( cur == f ) {
531 break;
532 }
533
534 ret.push_back( cur );
535 // Jumps are acceptable on 1 z-level changes
536 // This is because stairs teleport the player too
537 if( rl_dist( cur, par ) > 1 && std::abs( cur.z - par.z ) != 1 ) {
538 debugmsg( "Jump in our route! %d:%d:%d->%d:%d:%d",
539 cur.x, cur.y, cur.z, par.x, par.y, par.z );
540 return ret;
541 }
542
543 cur = par;
544 }
545
546 std::reverse( ret.begin(), ret.end() );
547 }
548
549 return ret;
550}
bool has_zlevels() const
Definition: map.h:1685
const pathfinding_cache & get_pathfinding_cache_ref(int zlev) const
Definition: map.cpp:8768
point tripoint_to_mount(const tripoint &p) const
Definition: vehicle.cpp:3130
const vehicle_part & cpart(int part_num) const
Definition: vehicle.cpp:7085
bool part_flag(int p, const std::string &f) const
Definition: vehicle.cpp:2911
bool allowed_move(const point &from, const point &to) const
Definition: vehicle.cpp:3220
@ TFLAG_GOES_DOWN
Definition: mapdata.h:308
@ TFLAG_GOES_UP
Definition: mapdata.h:309
Definition: gates.h:28
Definition: overmap.h:50
bool is_disjoint(const Set1 &set1, const Set2 &set2)
constexpr int flat_index(const tripoint &p)
Definition: pathfinding.cpp:34
@ ASL_CLOSED
Definition: pathfinding.cpp:30
@ ASL_NONE
Definition: pathfinding.cpp:28
@ PF_VEHICLE
Definition: pathfinding.h:11
@ PF_WALL
Definition: pathfinding.h:10
@ PF_CLIMBABLE
Definition: pathfinding.h:15
@ PF_UPDOWN
Definition: pathfinding.h:14
@ PF_TRAP
Definition: pathfinding.h:13
@ PF_SHARP
Definition: pathfinding.h:16
@ PF_SLOW
Definition: pathfinding.h:9
const trap & get_trap_t() const
Definition: submap.h:293
@ VPFLAG_OPENABLE
Definition: veh_type.h:44

References pathfinding_settings::allow_climb_stairs, pathfinding_settings::allow_open_doors, vehicle::allowed_move(), ASL_CLOSED, ASL_NONE, pathfinding_settings::avoid_rough_terrain, pathfinding_settings::avoid_sharp, pathfinding_settings::avoid_traps, bash(), bash_rating_internal(), pathfinding_settings::bash_strength, pathfinding_settings::climb_cost, clip_to_bounds(), vehicle::cpart(), debugmsg, detail::digits::done, flat_index(), furniture, maptile::get_furn_t(), get_pathfinding_cache_ref(), maptile::get_ter_t(), maptile::get_trap_t(), has_flag(), has_zlevels(), vehicle_part::hp(), inbounds(), is_disjoint(), is_outside(), line_to(), maptile_at_internal(), pathfinding_settings::max_dist, pathfinding_settings::max_length, move_cost_internal(), vpart_position::obstacle_at_part(), vehicle::part_flag(), PF_CLIMBABLE, PF_SHARP, PF_SLOW, PF_TRAP, PF_UPDOWN, PF_VEHICLE, PF_WALL, cata::hash64_detail::ret, rl_dist(), route(), terrain, TFLAG_GOES_DOWN, TFLAG_GOES_UP, TFLAG_NO_FLOOR, TFLAG_RAMP, TFLAG_RAMP_DOWN, TFLAG_RAMP_UP, vehicle::tripoint_to_mount(), valid_move(), veh_at_internal(), VPFLAG_OPENABLE, tripoint::x, tripoint::xy(), tripoint::y, and tripoint::z.

Referenced by activity_on_turn_move_loot(), add_item_or_charges(), npc::go_to_omt_destination(), game::handle_action(), game::list_items(), game::look_around(), perform_zone_activity_turn(), route(), route_adjacent(), activity_handlers::travel_do_turn(), game::try_get_left_click_action(), and npc::update_path().

◆ save()

void map::save ( )

Add currently loaded submaps (in grid) to the mapbuffer.

They will than be stored by that class and can be loaded from that class. This can be called several times, the mapbuffer takes care of adding the same submap several times. It should only be called after the map has been loaded. Submaps that have been loaded from the mapbuffer (and not generated) are already stored in the mapbuffer. TODO: determine if this is really needed? Submaps are already in the mapbuffer if they have been loaded from disc and the are added by map::generate, too. So when do they not appear in the mapbuffer?

Definition at line 6594 of file map.cpp.

6595{
6596 for( int gridx = 0; gridx < my_MAPSIZE; gridx++ ) {
6597 for( int gridy = 0; gridy < my_MAPSIZE; gridy++ ) {
6598 if( zlevels ) {
6599 for( int gridz = -OVERMAP_DEPTH; gridz <= OVERMAP_HEIGHT; gridz++ ) {
6600 saven( tripoint( gridx, gridy, gridz ) );
6601 }
6602 } else {
6603 saven( tripoint( gridx, gridy, abs_sub.z ) );
6604 }
6605 }
6606 }
6607}

References abs_sub, my_MAPSIZE, OVERMAP_DEPTH, OVERMAP_HEIGHT, saven(), tripoint::z, and zlevels.

Referenced by start_location::add_map_extra(), add_monsters(), start_location::burn(), talk_function::buy_100_logs(), talk_function::buy_10_logs(), create_lab_consoles(), construct::done_digormine_stair(), construct::done_mine_upstair(), farm_action(), talk_function::field_build_1(), talk_function::field_build_2(), talk_function::field_harvest(), talk_function::field_plant(), defense_game::init_map(), mission_start::kill_horde_master(), talk_function::loot_building(), om_cutdown_trees(), om_harvest_furn(), om_harvest_itm(), om_harvest_ter(), om_set_hide_site(), mission_start::place_deposit_box(), mission_start::place_dog(), mission_start::place_npc_software(), mission_start::place_priest_diary(), basecamp::place_results(), game::place_vehicle_nearby(), mission_start::place_zombie_mom(), start_location::prepare_map(), mission_start::ranch_nurse_1(), mission_start::ranch_nurse_2(), mission_start::ranch_nurse_3(), mission_start::ranch_nurse_4(), mission_start::ranch_nurse_5(), mission_start::ranch_nurse_6(), mission_start::ranch_nurse_7(), mission_start::ranch_nurse_8(), mission_start::ranch_nurse_9(), mission_start::ranch_scavenger_1(), mission_start::ranch_scavenger_2(), mission_start::ranch_scavenger_3(), mission_start::reveal_lab_train_depot(), game::save_maps(), and debug_menu::spawn_nested_mapgen().

◆ saven()

void map::saven ( const tripoint grid)
protected

Definition at line 6937 of file map.cpp.

6938{
6939 dbg( DL::Debug ) << "map::saven( world=" << abs_sub << ", grid=" << grid << " )";
6940 const int gridn = get_nonant( grid );
6941 submap *submap_to_save = getsubmap( gridn );
6942 if( submap_to_save == nullptr || submap_to_save->get_ter( point_zero ) == t_null ) {
6943 // This is a serious error and should be signaled as soon as possible
6944 debugmsg( "map::saven grid (%s) %s!", grid.to_string(),
6945 submap_to_save == nullptr ? "null" : "uninitialized" );
6946 return;
6947 }
6948
6949 const tripoint abs = abs_sub.xy() + grid;
6950
6951 if( !zlevels && grid.z != abs_sub.z ) {
6952 debugmsg( "Tried to save submap (%d,%d,%d) as (%d,%d,%d), which isn't supported in non-z-level builds",
6953 abs.x, abs.y, abs_sub.z, abs.x, abs.y, grid.z );
6954 }
6955
6956 dbg( DL::Debug ) << "map::saven abs: " << abs << " gridn: " << gridn;
6957
6958 // An edge case: restock_fruits relies on last_touched, so we must call it before save
6959 if( season_of_year( calendar::turn ) != season_of_year( submap_to_save->last_touched ) ) {
6960 const time_duration time_since_last_actualize = calendar::turn - submap_to_save->last_touched;
6961 for( int x = 0; x < SEEX; x++ ) {
6962 for( int y = 0; y < SEEY; y++ ) {
6963 const tripoint pnt = sm_to_ms_copy( grid ) + point( x, y );
6964 restock_fruits( pnt, time_since_last_actualize );
6965 }
6966 }
6967 }
6968
6969 submap_to_save->last_touched = calendar::turn;
6970 MAPBUFFER.add_submap( abs, submap_to_save );
6971}
bool add_submap(const tripoint &p, std::unique_ptr< submap > &sm)
Add a new submap to the buffer.
Definition: mapbuffer.cpp:68
@ Debug
Debug information (default: disabled).

References abs_sub, mapbuffer::add_submap(), dbg, Debug, debugmsg, get_nonant(), submap::get_ter(), getsubmap(), grid, submap::last_touched, MAPBUFFER, point_zero, restock_fruits(), season_of_year(), SEEX, SEEY, sm_to_ms_copy(), t_null, calendar::turn, tripoint::xy(), tripoint::z, and zlevels.

Referenced by generate(), and save().

◆ scent_blockers()

void map::scent_blockers ( std::array< std::array< char, MAPSIZE_X >, MAPSIZE_Y > &  scent_transfer,
const point min,
const point max 
)

Build the map of scent-resistant tiles.

Should be way faster than if done in game.cpp using public map functions.

Definition at line 8545 of file map.cpp.

8547{
8548 auto reduce = TFLAG_REDUCE_SCENT;
8549 auto block = TFLAG_NO_SCENT;
8550 auto fill_values = [&]( const tripoint & gp, const submap * sm, const point & lp ) {
8551 // We need to generate the x/y coordinates, because we can't get them "for free"
8552 const point p = lp + sm_to_ms_copy( gp.xy() );
8553 if( sm->get_ter( lp ).obj().has_flag( block ) ) {
8554 scent_transfer[p.x][p.y] = 0;
8555 } else if( sm->get_ter( lp ).obj().has_flag( reduce ) ||
8556 sm->get_furn( lp ).obj().has_flag( reduce ) ) {
8557 scent_transfer[p.x][p.y] = 1;
8558 } else {
8559 scent_transfer[p.x][p.y] = 5;
8560 }
8561
8562 return ITER_CONTINUE;
8563 };
8564
8565 function_over( tripoint( min, abs_sub.z ), tripoint( max, abs_sub.z ), fill_values );
8566
8567 const inclusive_rectangle<point> local_bounds( min, max );
8568
8569 // Now vehicles
8570
8571 auto vehs = get_vehicles();
8572 for( auto &wrapped_veh : vehs ) {
8573 vehicle &veh = *( wrapped_veh.v );
8574 for( const vpart_reference &vp : veh.get_any_parts( VPFLAG_OBSTACLE ) ) {
8575 const tripoint part_pos = vp.pos();
8576 if( local_bounds.contains( part_pos.xy() ) && scent_transfer[part_pos.x][part_pos.y] == 5 ) {
8577 scent_transfer[part_pos.x][part_pos.y] = 1;
8578 }
8579 }
8580
8581 // Doors, but only the closed ones
8582 for( const vpart_reference &vp : veh.get_any_parts( VPFLAG_OPENABLE ) ) {
8583 if( vp.part().open ) {
8584 continue;
8585 }
8586
8587 const tripoint part_pos = vp.pos();
8588 if( local_bounds.contains( part_pos.xy() ) && scent_transfer[part_pos.x][part_pos.y] == 5 ) {
8589 scent_transfer[part_pos.x][part_pos.y] = 1;
8590 }
8591 }
8592 }
8593}
void function_over(const tripoint &start, const tripoint &end, Functor fun) const
Runs a functor over given submaps over submaps in the area, getting next submap only when the current...
Definition: map.cpp:8491
@ TFLAG_REDUCE_SCENT
Definition: mapdata.h:278
@ TFLAG_NO_SCENT
Definition: mapdata.h:284
@ VPFLAG_OBSTACLE
Definition: veh_type.h:42

References abs_sub, inclusive_rectangle< Point, >::contains(), function_over(), vehicle::get_any_parts(), get_vehicles(), ITER_CONTINUE, coords::sm, sm_to_ms_copy(), TFLAG_NO_SCENT, TFLAG_REDUCE_SCENT, VPFLAG_OBSTACLE, VPFLAG_OPENABLE, point::x, tripoint::x, tripoint::xy(), point::y, tripoint::y, and tripoint::z.

Referenced by scent_map::update().

◆ sees() [1/2]

bool map::sees ( const tripoint F,
const tripoint T,
int  range 
) const

Returns whether F sees T with a view range of range.

Definition at line 6130 of file map.cpp.

6131{
6132 int dummy = 0;
6133 return sees( F, T, range, dummy );
6134}

References sees().

Referenced by apply_ammo_effects(), find_clear_path(), mattack::flame(), explosion_handler::explosion_funcs::flashbang(), get_heat_radiation(), projectile_attack(), Creature::sees(), sees(), Character::sees_with_infrared(), shake_vehicle(), shoot(), spawn_monsters_submap_group(), and vehicle_selector::vehicle_selector().

◆ sees() [2/2]

bool map::sees ( const tripoint F,
const tripoint T,
int  range,
int &  bresenham_slope 
) const
private

Don't expose the slope adjust outside map functions.

This one is internal-only, we don't want to expose the slope tweaking ickiness outside the map class.

Parameters
FThing doing the seeing
TThing being seen
rangeVision range of F
bresenham_slopeIndicates the start offset of Bresenham line used to connect the two points, and may subsequently be used to form a path between them. Set to zero if the function returns false.

Definition at line 6139 of file map.cpp.

6141{
6142 if( ( range >= 0 && range < rl_dist( F, T ) ) ||
6143 !inbounds( T ) ) {
6144 bresenham_slope = 0;
6145 return false; // Out of range!
6146 }
6147 // Cannonicalize the order of the tripoints so the cache is reflexive.
6148 const tripoint &min = F < T ? F : T;
6149 const tripoint &max = !( F < T ) ? F : T;
6150 // A little gross, just pack the values into a point.
6151 const point key(
6152 min.x << 16 | min.y << 8 | ( min.z + OVERMAP_DEPTH ),
6153 max.x << 16 | max.y << 8 | ( max.z + OVERMAP_DEPTH )
6154 );
6155 char cached = skew_vision_cache.get( key, -1 );
6156 if( cached >= 0 ) {
6157 return cached > 0;
6158 }
6159
6160 bool visible = true;
6161
6162 // Ugly `if` for now
6163 if( !fov_3d || F.z == T.z ) {
6164
6165 point last_point = F.xy();
6166 bresenham( F.xy(), T.xy(), bresenham_slope,
6167 [this, &visible, &T, &last_point]( const point & new_point ) {
6168 // Exit before checking the last square, it's still visible even if opaque.
6169 if( new_point.x == T.x && new_point.y == T.y ) {
6170 return false;
6171 }
6172 if( !this->is_transparent( tripoint( new_point, T.z ) ) ||
6173 obscured_by_vehicle_rotation( tripoint( last_point, T.z ), tripoint( new_point, T.z ) ) ) {
6174 visible = false;
6175 return false;
6176 }
6177 last_point = new_point;
6178 return true;
6179 } );
6180 skew_vision_cache.insert( 100000, key, visible ? 1 : 0 );
6181 return visible;
6182 }
6183
6184 tripoint last_point = F;
6185 bresenham( F, T, bresenham_slope, 0,
6186 [this, &visible, &T, &last_point]( const tripoint & new_point ) {
6187 // Exit before checking the last square if it's not a vertical transition,
6188 // it's still visible even if opaque.
6189 if( new_point == T && last_point.z == T.z ) {
6190 return false;
6191 }
6192
6193 // TODO: Allow transparent floors (and cache them!)
6194 if( new_point.z == last_point.z ) {
6195 if( !this->is_transparent( new_point ) || obscured_by_vehicle_rotation( last_point, new_point ) ) {
6196 visible = false;
6197 return false;
6198 }
6199 } else {
6200 const int max_z = std::max( new_point.z, last_point.z );
6201 if( ( has_floor_or_support( {new_point.xy(), max_z} ) ||
6202 !is_transparent( {new_point.xy(), last_point.z} ) ) &&
6203 ( has_floor_or_support( {last_point.xy(), max_z} ) ||
6204 !is_transparent( {last_point.xy(), new_point.z} ) ) ) {
6205 visible = false;
6206 return false;
6207 }
6208 }
6209
6210 last_point = new_point;
6211 return true;
6212 } );
6213 skew_vision_cache.insert( 100000, key, visible ? 1 : 0 );
6214 return visible;
6215}

References bresenham(), fov_3d, inbounds(), obscured_by_vehicle_rotation(), OVERMAP_DEPTH, rl_dist(), skew_vision_cache, tripoint::x, tripoint::xy(), tripoint::y, and tripoint::z.

◆ sees_some_items() [1/2]

bool map::sees_some_items ( const tripoint p,
const Creature who 
) const

Check if creature can see some items at p.

Includes:

  • check for items at this location (has_items(p))
  • check for SEALED flag (sealed furniture/terrain makes items not visible under any circumstances).
  • check for CONTAINER flag (makes items only visible when the creature is at p or at an adjacent square).

Definition at line 4725 of file map.cpp.

4726{
4727 // Can only see items if there are any items.
4728 return has_items( p ) && could_see_items( p, who.pos() );
4729}

References could_see_items(), has_items(), and Creature::pos().

Referenced by game::butcher(), editmap::draw_main_ui_overlay(), draw_maptile(), npc::find_corpse_to_pulp(), npc::find_item(), game::find_nearby_items(), vehicle::interact_with(), game::print_items_info(), and npc::see_item_say_smth().

◆ sees_some_items() [2/2]

bool map::sees_some_items ( const tripoint p,
const tripoint from 
) const

Definition at line 4731 of file map.cpp.

4732{
4733 return has_items( p ) && could_see_items( p, from );
4734}

References could_see_items(), and has_items().

◆ set() [1/2]

void map::set ( const point p,
const ter_id new_terrain,
const furn_id new_furniture 
)
inline

Definition at line 839 of file map.h.

839 {
840 furn_set( p, new_furniture );
841 ter_set( p, new_terrain );
842 }

References furn_set(), and ter_set().

◆ set() [2/2]

void map::set ( const tripoint p,
const ter_id new_terrain,
const furn_id new_furniture 
)

Definition at line 1319 of file map.cpp.

1320{
1321 furn_set( p, new_furniture );
1322 ter_set( p, new_terrain );
1323}

References furn_set(), and ter_set().

Referenced by farm_action(), talk_function::field_plant(), mapgen_function_json_base::formatted_set_incredibly_simple(), and activity_handlers::plant_seed_finish().

◆ set_abs_sub()

void map::set_abs_sub ( const tripoint p)
protected

Sets abs_sub, see there.

Uses the same coordinate system as abs_sub.

Definition at line 8271 of file map.cpp.

8272{
8273 abs_sub = p;
8274}

References abs_sub.

Referenced by fake_map::fake_map(), generate(), load(), shift(), and vertical_shift().

◆ set_field_age()

time_duration map::set_field_age ( const tripoint p,
const field_type_id type,
const time_duration age,
bool  isoffset = false 
)

Set age of field entry at point.

Parameters
pLocation of field
typeID of field
ageNew age of specified field
isoffsetIf true, the given age value is added to the existing value, if false, the existing age is ignored and overridden.
Returns
resulting age or -1_turns if not present (does not create a new field).

Definition at line 5327 of file map.cpp.

5329{
5330 if( field_entry *const field_ptr = get_field( p, type ) ) {
5331 return field_ptr->set_field_age( ( isoffset ? field_ptr->get_field_age() : 0_turns ) + age );
5332 }
5333 return -1_turns;
5334}

References get_field(), and type.

Referenced by game::grabbed_furn_move(), mod_field_age(), and game::walk_move().

◆ set_field_intensity()

int map::set_field_intensity ( const tripoint p,
const field_type_id type,
int  new_intensity,
bool  isoffset = false 
)

Set intensity of field entry at point, creating if not present, removing if intensity becomes 0.

Parameters
pLocation of field
typeID of field
new_intensityNew intensity of field
isoffsetIf true, the given new_intensity value is added to the existing value, if false, the existing intensity is ignored and overridden.
Returns
resulting intensity, or 0 for not present (either removed or not created at all).

Definition at line 5340 of file map.cpp.

5343{
5344 field_entry *field_ptr = get_field( p, type );
5345 if( field_ptr != nullptr ) {
5346 int adj = ( isoffset ? field_ptr->get_field_intensity() : 0 ) + new_intensity;
5347 if( adj > 0 ) {
5348 field_ptr->set_field_intensity( adj );
5349 return adj;
5350 } else {
5351 remove_field( p, type );
5352 return 0;
5353 }
5354 } else if( 0 + new_intensity > 0 ) {
5355 return add_field( p, type, new_intensity ) ? new_intensity : 0;
5356 }
5357
5358 return 0;
5359}

References add_field(), get_field(), field_entry::get_field_intensity(), remove_field(), field_entry::set_field_intensity(), and type.

Referenced by editmap::edit_fld(), game::grabbed_furn_move(), mod_field_intensity(), and game::walk_move().

◆ set_floor_cache_dirty()

void map::set_floor_cache_dirty ( const int  zlev)
inline

◆ set_graffiti()

void map::set_graffiti ( const tripoint p,
const std::string &  contents 
)

Definition at line 7802 of file map.cpp.

7803{
7804 if( !inbounds( p ) ) {
7805 return;
7806 }
7807 point l;
7808 submap *const current_submap = get_submap_at( p, l );
7809 current_submap->set_graffiti( l, contents );
7810}
void set_graffiti(const point &p, const std::string &new_graffiti)
Definition: submap.cpp:97

References get_submap_at(), inbounds(), and submap::set_graffiti().

Referenced by jmapgen_graffiti::apply().

◆ set_memory_seen_cache_dirty()

void map::set_memory_seen_cache_dirty ( const tripoint p)
inline

Definition at line 468 of file map.h.

468 {
469 const int offset = p.x + p.y * MAPSIZE_Y;
470 if( offset >= 0 && offset < MAPSIZE_X * MAPSIZE_Y ) {
471 get_cache( p.z ).map_memory_seen_cache.reset( offset );
472 }
473 }

References get_cache(), level_cache::map_memory_seen_cache, MAPSIZE_X, MAPSIZE_Y, tripoint::x, tripoint::y, and tripoint::z.

Referenced by furn_set(), vehicle::stop(), and ter_set().

◆ set_outside_cache_dirty()

void map::set_outside_cache_dirty ( const int  zlev)
inline

Definition at line 447 of file map.h.

447 {
448 if( inbounds_z( zlev ) ) {
449 get_cache( zlev ).outside_cache_dirty = true;
450 }
451 }

References get_cache(), inbounds_z(), and level_cache::outside_cache_dirty.

Referenced by draw_fill_background(), furn_set(), loadn(), editmap::mapgen_preview(), on_vehicle_moved(), ter_set(), and game::vertical_shift().

◆ set_pathfinding_cache_dirty()

void map::set_pathfinding_cache_dirty ( int  zlev)

◆ set_radiation() [1/2]

void map::set_radiation ( const point p,
const int  value 
)
inline

Definition at line 1215 of file map.h.

1215 {
1216 set_radiation( tripoint( p, abs_sub.z ), value );
1217 }

References abs_sub, set_radiation(), and tripoint::z.

◆ set_radiation() [2/2]

void map::set_radiation ( const tripoint p,
int  value 
)

Definition at line 4035 of file map.cpp.

4036{
4037 if( !inbounds( p ) ) {
4038 return;
4039 }
4040
4041 point l;
4042 submap *const current_submap = get_submap_at( p, l );
4043
4044 current_submap->set_radiation( l, value );
4045}

References get_submap_at(), inbounds(), and submap::set_radiation().

Referenced by jmapgen_setmap::apply(), create_anomaly(), draw_lab(), mapgen_crater(), mapgen_null(), mapgen_test(), and set_radiation().

◆ set_seen_cache_dirty() [1/2]

void map::set_seen_cache_dirty ( const int  zlevel)
inline

Definition at line 440 of file map.h.

440 {
441 if( inbounds_z( zlevel ) ) {
442 level_cache &cache = get_cache( zlevel );
443 cache.seen_cache_dirty = true;
444 }
445 }

References get_cache(), inbounds_z(), and level_cache::seen_cache_dirty.

◆ set_seen_cache_dirty() [2/2]

void map::set_seen_cache_dirty ( const tripoint  change_location)
inline

Definition at line 426 of file map.h.

426 {
427 if( inbounds( change_location ) ) {
428 level_cache &cache = get_cache( change_location.z );
429 if( cache.seen_cache_dirty ) {
430 return;
431 }
432 if( cache.seen_cache[change_location.x][change_location.y] != 0.0 ||
433 cache.camera_cache[change_location.x][change_location.y] != 0.0 ) {
434 cache.seen_cache_dirty = true;
435 }
436 }
437 }

References level_cache::camera_cache, get_cache(), inbounds(), level_cache::seen_cache, level_cache::seen_cache_dirty, tripoint::x, tripoint::y, and tripoint::z.

Referenced by add_field(), draw_fill_background(), furn_set(), loadn(), trapfunc::map_regen(), vehicle::merge_rackable_vehicle(), vehicle::open_or_close(), process_fields_in_submap(), remove_field(), avatar::set_movement_mode(), DefaultRemovePartHandler::set_transparency_cache_dirty(), vehicle::split_vehicles(), ter_set(), and weather_manager::update_weather().

◆ set_signage()

void map::set_signage ( const tripoint p,
const std::string &  message 
) const

Definition at line 4000 of file map.cpp.

4001{
4002 if( !inbounds( p ) ) {
4003 return;
4004 }
4005
4006 point l;
4007 submap *const current_submap = get_submap_at( p, l );
4008
4009 current_submap->set_signage( l, message );
4010}
void set_signage(const point &p, const std::string &s)
Definition: submap.cpp:137
std::string message
Definition: mapgen.cpp:407

References get_submap_at(), inbounds(), mapgen_defer::message, and submap::set_signage().

Referenced by jmapgen_sign::apply(), MapExtras::mx_grave(), MapExtras::mx_minefield(), and iexamine::sign().

◆ set_suspension_cache_dirty()

void map::set_suspension_cache_dirty ( const int  zlev)
inline

Definition at line 459 of file map.h.

459 {
460 if( inbounds_z( zlev ) ) {
461 get_cache( zlev ).suspension_cache_dirty = true;
462 }
463 }

References get_cache(), inbounds_z(), and level_cache::suspension_cache_dirty.

Referenced by loadn(), editmap::mapgen_preview(), and ter_set().

◆ set_temperature() [1/2]

void map::set_temperature ( const point p,
int  new_temperature 
)
inline

Definition at line 1232 of file map.h.

1232 {
1233 set_temperature( tripoint( p, abs_sub.z ), new_temperature );
1234 }

References abs_sub, set_temperature(), and tripoint::z.

◆ set_temperature() [2/2]

void map::set_temperature ( const tripoint p,
int  temperature 
)

Definition at line 4069 of file map.cpp.

4070{
4071 if( !inbounds( p ) ) {
4072 return;
4073 }
4074
4075 get_submap_at( p )->set_temperature( new_temperature );
4076}
void set_temperature(int new_temperature)
Definition: submap.h:198

References get_submap_at(), inbounds(), and submap::set_temperature().

Referenced by draw_lab(), and set_temperature().

◆ set_transparency_cache_dirty() [1/2]

void map::set_transparency_cache_dirty ( const int  zlev)
inline

◆ set_transparency_cache_dirty() [2/2]

void map::set_transparency_cache_dirty ( const tripoint p)
inline

Definition at line 419 of file map.h.

419 {
420 if( inbounds( p ) ) {
421 const tripoint smp = ms_to_sm_copy( p );
422 get_cache( smp.z ).transparency_cache_dirty.set( smp.x * MAPSIZE + smp.y );
423 }
424 }

References get_cache(), inbounds(), MAPSIZE, ms_to_sm_copy(), level_cache::transparency_cache_dirty, tripoint::x, tripoint::y, and tripoint::z.

◆ setsubmap()

void map::setsubmap ( size_t  grididx,
submap smap 
)
protected

Set the submap pointer in grid at the give index.

This is the inverse of getsubmap, any existing pointer is overwritten. The index must be valid. The given submap pointer must not be null.

Definition at line 8290 of file map.cpp.

8291{
8292 if( grididx >= grid.size() ) {
8293 debugmsg( "Tried to access invalid grid index %d", grididx );
8294 return;
8295 } else if( smap == nullptr ) {
8296 debugmsg( "Tried to set NULL submap pointer at index %d", grididx );
8297 return;
8298 }
8299 grid[grididx] = smap;
8300}

References debugmsg, and grid.

Referenced by copy_grid(), fake_map::fake_map(), generate(), and loadn().

◆ shake_vehicle()

units::angle map::shake_vehicle ( vehicle veh,
int  velocity_before,
units::angle  direction 
)
Strength reduces chance of being thrown from your seat when not wearing a seatbelt Strength reduces chance of being thrown from your seat when not wearing a seatbelt Dexterity reduces chance of losing control of vehicle when shaken Driving reduces chance of losing control of vehicle when shaken Strength reduces distance thrown from seat in a vehicle impact

Definition at line 1631 of file vehicle_move.cpp.

1633{
1634 const int d_vel = std::abs( veh.velocity - velocity_before ) / 100;
1635
1636 std::vector<rider_data> riders = veh.get_riders();
1637
1638 units::angle coll_turn = 0_degrees;
1639 for( const rider_data &r : riders ) {
1640 const int ps = r.prt;
1641 Creature *rider = r.psg;
1642 if( rider == nullptr ) {
1643 debugmsg( "throw passenger: empty passenger at part %d", ps );
1644 continue;
1645 }
1646
1647 const tripoint part_pos = veh.global_part_pos3( ps );
1648 if( rider->pos() != part_pos ) {
1649 debugmsg( "throw passenger: passenger at %d,%d,%d, part at %d,%d,%d",
1650 rider->posx(), rider->posy(), rider->posz(),
1651 part_pos.x, part_pos.y, part_pos.z );
1653 continue;
1654 }
1655
1656 player *psg = dynamic_cast<player *>( rider );
1657 monster *pet = dynamic_cast<monster *>( rider );
1658
1659 bool throw_from_seat = false;
1660 int move_resist = 1;
1661 if( psg ) {
1662 ///\EFFECT_STR reduces chance of being thrown from your seat when not wearing a seatbelt
1663 move_resist = psg->str_cur * 150 + 500;
1664 } else {
1665 int pet_resist = 0;
1666 if( pet != nullptr ) {
1667 pet_resist = static_cast<int>( to_kilogram( pet->get_weight() ) * 200 );
1668 }
1669 move_resist = std::max( 100, pet_resist );
1670 }
1671 if( veh.part_with_feature( ps, VPFLAG_SEATBELT, true ) == -1 ) {
1672 ///\EFFECT_STR reduces chance of being thrown from your seat when not wearing a seatbelt
1673 throw_from_seat = d_vel * rng( 80, 120 ) > move_resist;
1674 }
1675
1676 // Damage passengers if d_vel is too high
1677 if( !throw_from_seat && ( 10 * d_vel ) > 6 * rng( 50, 100 ) ) {
1678 const int dmg = d_vel * rng( 70, 100 ) / 400;
1679 if( psg ) {
1680 psg->hurtall( dmg, nullptr );
1682 _( "You take %d damage by the power of the impact!" ),
1683 _( "<npcname> takes %d damage by the power of the "
1684 "impact!" ), dmg );
1685 } else {
1686 pet->apply_damage( nullptr, bodypart_id( "torso" ), dmg );
1687 }
1688 }
1689
1690 if( psg && veh.player_in_control( *psg ) ) {
1691 const int lose_ctrl_roll = rng( 0, d_vel );
1692 ///\EFFECT_DEX reduces chance of losing control of vehicle when shaken
1693
1694 ///\EFFECT_DRIVING reduces chance of losing control of vehicle when shaken
1695 if( lose_ctrl_roll > psg->dex_cur * 2 + psg->get_skill_level( skill_driving ) * 3 ) {
1697 _( "You lose control of the %s." ),
1698 _( "<npcname> loses control of the %s." ), veh.name );
1699 int turn_amount = rng( 1, 3 ) * std::sqrt( std::abs( veh.velocity ) ) / 30;
1700 if( turn_amount < 1 ) {
1701 turn_amount = 1;
1702 }
1703 units::angle turn_angle = std::min( turn_amount * 15_degrees, 120_degrees );
1704 coll_turn = one_in( 2 ) ? turn_angle : -turn_angle;
1705 }
1706 }
1707
1708 if( throw_from_seat ) {
1709 if( psg ) {
1711 _( "You are hurled from the %s's seat by "
1712 "the power of the impact!" ),
1713 _( "<npcname> is hurled from the %s's seat by "
1714 "the power of the impact!" ), veh.name );
1715 unboard_vehicle( part_pos );
1716 } else if( get_player_character().sees( part_pos ) ) {
1717 add_msg( m_bad, _( "The %s is hurled from %s's by the power of the impact!" ),
1718 pet->disp_name(), veh.name );
1719 }
1720 ///\EFFECT_STR reduces distance thrown from seat in a vehicle impact
1721 g->fling_creature( rider, direction + rng_float( -30_degrees, 30_degrees ),
1722 std::max( 10, d_vel - move_resist / 100 ) );
1723 }
1724 }
1725
1726 return coll_turn;
1727}
int dex_cur
Definition: character.h:248
int get_skill_level(const skill_id &ident) const
Definition: character.cpp:3356
units::mass get_weight() const override
Definition: monster.cpp:2698
std::string disp_name(bool possessive=false, bool capitalize_first=false) const override
Definition: monster.cpp:537
int part_with_feature(int p, const std::string &f, bool unbroken) const
Definition: vehicle.cpp:2520
@ VPFLAG_SEATBELT
Definition: veh_type.h:45
static const skill_id skill_driving("driving")

References _, add_msg(), player::add_msg_player_or_npc(), monster::apply_damage(), debugmsg, Character::dex_cur, monster::disp_name(), g, get_player_character(), vehicle::get_riders(), Character::get_skill_level(), monster::get_weight(), vehicle::global_part_pos3(), Character::hurtall(), m_bad, m_warning, vehicle::name, one_in(), vehicle::part(), vehicle::part_with_feature(), vehicle_part::passenger_flag, vehicle::player_in_control(), Creature::pos(), Creature::posx(), Creature::posy(), Creature::posz(), vehicle_part::remove_flag(), rng(), rng_float(), sees(), skill_driving, Character::str_cur, units::to_kilogram(), unboard_vehicle(), vehicle::velocity, VPFLAG_SEATBELT, tripoint::x, tripoint::y, and tripoint::z.

Referenced by move_vehicle().

◆ shift()

void map::shift ( const point s)

Shift the map along the vector s.

This is like loading the map with coordinates derived from the current position of the map (abs_sub) plus the shift vector. Note: the map must have been loaded before this can be called.

Definition at line 6766 of file map.cpp.

6767{
6768 // Special case of 0-shift; refresh the map
6769 if( sp == point_zero ) {
6770 return; // Skip this?
6771 }
6772
6773 if( std::abs( sp.x ) > 1 || std::abs( sp.y ) > 1 ) {
6774 debugmsg( "map::shift called with a shift of more than one submap" );
6775 }
6776
6777 const tripoint abs = get_abs_sub();
6778
6779 set_abs_sub( abs + sp );
6780
6781 // if player is in vehicle, (s)he must be shifted with vehicle too
6782 if( g->u.in_vehicle ) {
6783 g->u.setx( g->u.posx() - sp.x * SEEX );
6784 g->u.sety( g->u.posy() - sp.y * SEEY );
6785 }
6786
6787 g->shift_destination_preview( point( -sp.x * SEEX, -sp.y * SEEY ) );
6788
6789 shift_traps( tripoint( sp, 0 ) );
6790
6791 vehicle *remoteveh = g->remoteveh();
6792
6793 const int zmin = zlevels ? -OVERMAP_DEPTH : abs.z;
6794 const int zmax = zlevels ? OVERMAP_HEIGHT : abs.z;
6795 for( int gridz = zmin; gridz <= zmax; gridz++ ) {
6796 for( vehicle *veh : get_cache( gridz ).vehicle_list ) {
6797 veh->zones_dirty = true;
6798 }
6799 }
6800
6801 constexpr half_open_rectangle<point> boundaries_2d( point_zero, point( MAPSIZE_Y, MAPSIZE_X ) );
6802 const point shift_offset_pt( -sp.x * SEEX, -sp.y * SEEY );
6803
6804 // Clear vehicle list and rebuild after shift
6806 // Shift the map sx submaps to the right and sy submaps down.
6807 // sx and sy should never be bigger than +/-1.
6808 // absx and absy are our position in the world, for saving/loading purposes.
6809 for( int gridz = zmin; gridz <= zmax; gridz++ ) {
6810 clear_vehicle_list( gridz );
6811 shift_bitset_cache<MAPSIZE_X, SEEX>( get_cache( gridz ).map_memory_seen_cache, sp );
6812 shift_bitset_cache<MAPSIZE, 1>( get_cache( gridz ).field_cache, sp );
6813 if( sp.x >= 0 ) {
6814 for( int gridx = 0; gridx < my_MAPSIZE; gridx++ ) {
6815 if( sp.y >= 0 ) {
6816 for( int gridy = 0; gridy < my_MAPSIZE; gridy++ ) {
6817 if( ( sp.x > 0 && gridx == 0 ) || ( sp.y > 0 && gridy == 0 ) ) {
6818 submaps_with_active_items.erase( { abs.x + gridx, abs.y + gridy, gridz } );
6819 }
6820 if( gridx + sp.x < my_MAPSIZE && gridy + sp.y < my_MAPSIZE ) {
6821 copy_grid( tripoint( gridx, gridy, gridz ),
6822 tripoint( gridx + sp.x, gridy + sp.y, gridz ) );
6823 update_vehicle_list( get_submap_at_grid( {gridx, gridy, gridz} ), gridz );
6824 } else {
6825 loadn( tripoint( gridx, gridy, gridz ), true );
6826 }
6827 }
6828 } else { // sy < 0; work through it backwards
6829 for( int gridy = my_MAPSIZE - 1; gridy >= 0; gridy-- ) {
6830 if( ( sp.x > 0 && gridx == 0 ) || gridy == my_MAPSIZE - 1 ) {
6831 submaps_with_active_items.erase( { abs.x + gridx, abs.y + gridy, gridz } );
6832 }
6833 if( gridx + sp.x < my_MAPSIZE && gridy + sp.y >= 0 ) {
6834 copy_grid( tripoint( gridx, gridy, gridz ),
6835 tripoint( gridx + sp.x, gridy + sp.y, gridz ) );
6836 update_vehicle_list( get_submap_at_grid( { gridx, gridy, gridz } ), gridz );
6837 } else {
6838 loadn( tripoint( gridx, gridy, gridz ), true );
6839 }
6840 }
6841 }
6842 }
6843 } else { // sx < 0; work through it backwards
6844 for( int gridx = my_MAPSIZE - 1; gridx >= 0; gridx-- ) {
6845 if( sp.y >= 0 ) {
6846 for( int gridy = 0; gridy < my_MAPSIZE; gridy++ ) {
6847 if( gridx == my_MAPSIZE - 1 || ( sp.y > 0 && gridy == 0 ) ) {
6848 submaps_with_active_items.erase( { abs.x + gridx, abs.y + gridy, gridz } );
6849 }
6850 if( gridx + sp.x >= 0 && gridy + sp.y < my_MAPSIZE ) {
6851 copy_grid( tripoint( gridx, gridy, gridz ),
6852 tripoint( gridx + sp.x, gridy + sp.y, gridz ) );
6853 update_vehicle_list( get_submap_at_grid( { gridx, gridy, gridz } ), gridz );
6854 } else {
6855 loadn( tripoint( gridx, gridy, gridz ), true );
6856 }
6857 }
6858 } else { // sy < 0; work through it backwards
6859 for( int gridy = my_MAPSIZE - 1; gridy >= 0; gridy-- ) {
6860 if( gridx == my_MAPSIZE - 1 || gridy == my_MAPSIZE - 1 ) {
6861 submaps_with_active_items.erase( { abs.x + gridx, abs.y + gridy, gridz } );
6862 }
6863 if( gridx + sp.x >= 0 && gridy + sp.y >= 0 ) {
6864 copy_grid( tripoint( gridx, gridy, gridz ),
6865 tripoint( gridx + sp.x, gridy + sp.y, gridz ) );
6866 update_vehicle_list( get_submap_at_grid( { gridx, gridy, gridz } ), gridz );
6867 } else {
6868 loadn( tripoint( gridx, gridy, gridz ), true );
6869 }
6870 }
6871 }
6872 }
6873 }
6874 }
6875 if( zlevels ) {
6876 //Go through the generated maps and fill in the roofs
6877 for( int gridz = zmin; gridz <= zmax; gridz++ ) {
6878 if( sp.x > 0 ) {
6879 for( int gridy = 0; gridy < my_MAPSIZE; gridy++ ) {
6880 add_roofs( {my_MAPSIZE - 1, gridy, gridz} );
6881 }
6882 } else if( sp.x < 0 ) {
6883 for( int gridy = 0; gridy < my_MAPSIZE; gridy++ ) {
6884 add_roofs( {0, gridy, gridz} );
6885 }
6886 }
6887
6888 if( sp.y > 0 ) {
6889 for( int gridx = 0; gridx < my_MAPSIZE; gridx++ ) {
6890 add_roofs( {gridx, my_MAPSIZE - 1, gridz} );
6891 }
6892 } else if( sp.y < 0 ) {
6893 for( int gridx = 0; gridx < my_MAPSIZE; gridx++ ) {
6894 add_roofs( {gridx, 0, gridz} );
6895 }
6896 }
6897 }
6898 }
6899
6901
6902 g->setremoteveh( remoteveh );
6903
6904 if( !support_cache_dirty.empty() ) {
6905 shift_tripoint_set( support_cache_dirty, shift_offset_pt, boundaries_2d );
6906 }
6907}
void copy_grid(const tripoint &to, const tripoint &from)
Definition: map.cpp:7507
void shift_traps(const tripoint &shift)
As part of the map shifting, this shifts the trap locations stored in traplocs.
Definition: map.cpp:6634
template void shift_bitset_cache< MAPSIZE_X, SEEX >(std::bitset< MAPSIZE_X *MAPSIZE_X > &cache, const point &s)
static void shift_tripoint_set(std::set< tripoint > &set, const point &offset, const half_open_rectangle< point > &boundaries)
Definition: map.cpp:6693
template void shift_bitset_cache< MAPSIZE, 1 >(std::bitset< MAPSIZE *MAPSIZE > &cache, const point &s)
int remoteveh(player *, item *, bool, const tripoint &)
Definition: iuse.cpp:8254

References add_roofs(), clear_vehicle_cache(), clear_vehicle_list(), copy_grid(), debugmsg, g, get_abs_sub(), get_cache(), get_submap_at_grid(), loadn(), MAPSIZE_X, MAPSIZE_Y, my_MAPSIZE, OVERMAP_DEPTH, OVERMAP_HEIGHT, point_zero, iuse::remoteveh(), reset_vehicle_cache(), SEEX, SEEY, set_abs_sub(), shift_bitset_cache< MAPSIZE, 1 >(), shift_bitset_cache< MAPSIZE_X, SEEX >(), shift_traps(), shift_tripoint_set(), submaps_with_active_items, support_cache_dirty, update_vehicle_list(), point::x, point::y, and zlevels.

Referenced by shift_traps(), and game::update_map().

◆ shift_traps()

void map::shift_traps ( const tripoint shift)
protected

As part of the map shifting, this shifts the trap locations stored in traplocs.

Parameters
shiftThe amount shifting in submap, the same as go into shift.

Definition at line 6634 of file map.cpp.

6635{
6636 // Offset needs to have sign opposite to shift direction
6637 const tripoint offset( -shift.x * SEEX, -shift.y * SEEY, -shift.z );
6638 for( auto iter = field_furn_locs.begin(); iter != field_furn_locs.end(); ) {
6639 tripoint &pos = *iter;
6640 pos += offset;
6641 if( inbounds( pos ) ) {
6642 ++iter;
6643 } else {
6644 iter = field_furn_locs.erase( iter );
6645 }
6646 }
6647 for( auto &traps : traplocs ) {
6648 for( auto iter = traps.begin(); iter != traps.end(); ) {
6649 tripoint &pos = *iter;
6650 pos += offset;
6651 if( inbounds( pos ) ) {
6652 ++iter;
6653 } else {
6654 // Theoretical enhancement: if this is not the last entry of the vector,
6655 // move the last entry into pos and remove the last entry instead of iter.
6656 // This would avoid moving all the remaining entries.
6657 iter = traps.erase( iter );
6658 }
6659 }
6660 }
6661}
void shift(const point &s)
Shift the map along the vector s.
Definition: map.cpp:6766

References field_furn_locs, inbounds(), SEEX, SEEY, shift(), and traplocs.

Referenced by shift().

◆ shift_vehicle_z()

void map::shift_vehicle_z ( vehicle veh,
int  z_shift 
)

Definition at line 6720 of file map.cpp.

6721{
6722
6723 tripoint src = veh.global_pos3();
6724 tripoint dst = src + tripoint_above * z_shift;
6725
6726 submap *src_submap = get_submap_at( src );
6727 submap *dst_submap = get_submap_at( dst );
6728
6729 int our_i = -1;
6730 for( size_t i = 0; i < src_submap->vehicles.size(); i++ ) {
6731 if( src_submap->vehicles[i].get() == &veh ) {
6732 our_i = i;
6733 break;
6734 }
6735 }
6736
6737 if( our_i == -1 ) {
6738 debugmsg( "shift_vehicle [%s] failed could not find vehicle", veh.name );
6739 return;
6740 }
6741
6742 for( auto &prt : veh.get_all_parts() ) {
6743 prt.part().precalc[0].z -= z_shift;
6744 }
6745
6746 veh.set_submap_moved( tripoint( dst.x / SEEX, dst.y / SEEY, dst.z ) );
6747 auto src_submap_veh_it = src_submap->vehicles.begin() + our_i;
6748 dst_submap->vehicles.push_back( std::move( *src_submap_veh_it ) );
6749 src_submap->vehicles.erase( src_submap_veh_it );
6750 dst_submap->is_uniform = false;
6752
6753 update_vehicle_list( dst_submap, dst.z );
6754
6755 level_cache &ch = get_cache( src.z );
6756 for( const vehicle *elem : ch.vehicle_list ) {
6757 if( elem == &veh ) {
6758 ch.vehicle_list.erase( &veh );
6759 ch.zone_vehicles.erase( &veh );
6760 break;
6761 }
6762 }
6763
6764}

References debugmsg, vehicle::get_all_parts(), get_cache(), get_submap_at(), vehicle::global_pos3(), invalidate_max_populated_zlev(), submap::is_uniform, avatar_action::move(), vehicle::name, SEEX, SEEY, vehicle::set_submap_moved(), tripoint_above, update_vehicle_list(), level_cache::vehicle_list, submap::vehicles, tripoint::x, tripoint::y, tripoint::z, and level_cache::zone_vehicles.

Referenced by vehicle::shift_zlevel().

◆ shoot()

void map::shoot ( const tripoint p,
projectile proj,
bool  hit_items 
)

Definition at line 3714 of file map.cpp.

3715{
3716 float initial_damage = 0.0;
3717 for( const damage_unit &dam : proj.impact ) {
3718 initial_damage += dam.amount * dam.damage_multiplier;
3719 initial_damage += dam.res_pen;
3720 }
3721 if( initial_damage < 0 ) {
3722 return;
3723 }
3724
3725 float dam = initial_damage;
3726
3727 if( has_flag( "ALARMED", p ) && !g->timed_events.queued( TIMED_EVENT_WANTED ) ) {
3728 sounds::sound( p, 30, sounds::sound_t::alarm, _( "an alarm sound!" ), true, "environment",
3729 "alarm" );
3730 const tripoint abs = ms_to_sm_copy( getabs( p ) );
3731 g->timed_events.add( TIMED_EVENT_WANTED, calendar::turn + 30_minutes, 0, abs );
3732 }
3733
3734 const bool inc = proj.has_effect( ammo_effect_INCENDIARY ) ||
3735 proj.impact.type_damage( DT_HEAT ) > 0;
3736 if( const optional_vpart_position vp = veh_at( p ) ) {
3737 dam = vp->vehicle().damage( vp->part_index(), dam, inc ? DT_HEAT : DT_STAB, hit_items );
3738 }
3739
3740 ter_id terrain = ter( p );
3741 ter_t ter = terrain.obj();
3742
3743 if( ter.bash.ranged ) {
3744 const ranged_bash_info &ri = *ter.bash.ranged;
3745 if( !hit_items && !check( ri.block_unaimed_chance ) ) {
3746 // Nothing, it's a miss
3747 } else if( ri.reduction_laser && proj.has_effect( ammo_effect_LASER ) ) {
3748 dam -= rng( ri.reduction_laser->min, ri.reduction_laser->max );
3749 } else {
3750 dam -= rng( ri.reduction.min, ri.reduction.max );
3751 if( dam > ri.destroy_threshold ) {
3752 bash_params params{0, false, true, hit_items, 1.0, false};
3753 bash_ter_success( p, params );
3754 }
3755 if( dam <= 0 && is_transparent( p ) && get_avatar().sees( p ) ) {
3756 add_msg( _( "The shot is stopped by the %s!" ), tername( p ) );
3757 }
3758 if( ri.flammable && inc ) {
3759 add_field( p, fd_fire, 1 );
3760 }
3761 }
3762 } else if( impassable( p ) && !is_transparent( p ) ) {
3763 bash( p, dam, false );
3764 // TODO: Preserve some residual damage when it makes sense.
3765 dam = 0;
3766 }
3767
3768 for( const ammo_effect_str_id &ae_id : proj.get_ammo_effects() ) {
3769 const ammo_effect &ae = *ae_id;
3770 if( ae.trail_field_type ) {
3771 if( x_in_y( ae.trail_chance, 100 ) ) {
3773 }
3774 }
3775 }
3776
3777 dam = std::max( 0.0f, dam );
3778
3779 // Check fields?
3780 const field_entry *fieldhit = get_field( p, fd_web );
3781 if( fieldhit != nullptr ) {
3782 if( inc ) {
3783 add_field( p, fd_fire, fieldhit->get_field_intensity() - 1 );
3784 } else if( dam > 5 + fieldhit->get_field_intensity() * 5 &&
3785 one_in( 5 - fieldhit->get_field_intensity() ) ) {
3786 dam -= rng( 1, 2 + fieldhit->get_field_intensity() * 2 );
3787 remove_field( p, fd_web );
3788 }
3789 }
3790
3791 // Rescale the damage
3792 if( dam <= 0 ) {
3793 proj.impact.damage_units.clear();
3794 return;
3795 } else if( dam < initial_damage ) {
3796 proj.impact.mult_damage( dam / static_cast<double>( initial_damage ) );
3797 }
3798
3799 //Projectiles with NO_ITEM_DAMAGE flag won't damage items at all
3800 if( !hit_items || !inbounds( p ) ) {
3801 return;
3802 }
3803
3804 // Make sure the message is sensible for the ammo effects. Lasers aren't projectiles.
3805 std::string damage_message;
3806 if( proj.has_effect( ammo_effect_LASER ) ) {
3807 damage_message = _( "laser beam" );
3808 } else if( proj.has_effect( ammo_effect_LIGHTNING ) ) {
3809 damage_message = _( "bolt of electricity" );
3810 } else if( proj.has_effect( ammo_effect_PLASMA ) ) {
3811 damage_message = _( "bolt of plasma" );
3812 } else {
3813 damage_message = _( "flying projectile" );
3814 }
3815
3816 smash_items( p, dam, damage_message, false );
3817}
avatar & get_avatar()
Definition: avatar.cpp:102
@ DT_STAB
Definition: damage.h:27
static const ammo_effect_str_id ammo_effect_LIGHTNING("LIGHTNING")
static const ammo_effect_str_id ammo_effect_LASER("LASER")
static const ammo_effect_str_id ammo_effect_INCENDIARY("INCENDIARY")
static const ammo_effect_str_id ammo_effect_PLASMA("PLASMA")
int check(unformattable)
Definition: fmtlib_core.h:1610
int trail_chance
Definition: ammo_effect.h:45
int trail_intensity_max
Definition: ammo_effect.h:44
int trail_intensity_min
Definition: ammo_effect.h:43
field_type_id trail_field_type
Definition: ammo_effect.h:40
std::vector< damage_unit > damage_units
Definition: damage.h:52
float type_damage(damage_type dt) const
Definition: damage.cpp:64
void mult_damage(double multiplier, bool pre_armor=false)
Definition: damage.cpp:48
float amount
Definition: damage.h:37
float damage_multiplier
Definition: damage.h:40
float res_pen
Definition: damage.h:38
const std::set< ammo_effect_str_id > & get_ammo_effects()
Definition: projectile.h:42
damage_instance impact
Definition: projectile.h:21
bool has_effect(const ammo_effect_str_id &id) const
Definition: projectile.h:55
bool flammable
Definition: mapdata.h:40
numeric_interval< int > reduction
Definition: mapdata.h:36
cata::optional< numeric_interval< int > > reduction_laser
Definition: mapdata.h:38
int destroy_threshold
Definition: mapdata.h:39
units::probability block_unaimed_chance
Definition: mapdata.h:41

References _, add_field(), add_msg(), sounds::alarm, ammo_effect_INCENDIARY, ammo_effect_LASER, ammo_effect_LIGHTNING, ammo_effect_PLASMA, damage_unit::amount, bash(), bash_ter_success(), ranged_bash_info::block_unaimed_chance, detail::check(), damage_unit::damage_multiplier, damage_instance::damage_units, ranged_bash_info::destroy_threshold, DT_HEAT, DT_STAB, fd_fire, fd_web, ranged_bash_info::flammable, g, projectile::get_ammo_effects(), get_avatar(), get_field(), field_entry::get_field_intensity(), getabs(), projectile::has_effect(), has_flag(), projectile::impact, impassable(), inbounds(), is_transparent(), ms_to_sm_copy(), damage_instance::mult_damage(), one_in(), ranged_bash_info::reduction, ranged_bash_info::reduction_laser, remove_field(), damage_unit::res_pen, rng(), sees(), smash_items(), sounds::sound(), ter(), tername(), terrain, TIMED_EVENT_WANTED, ammo_effect::trail_chance, ammo_effect::trail_field_type, ammo_effect::trail_intensity_max, ammo_effect::trail_intensity_min, calendar::turn, damage_instance::type_damage(), veh_at(), and x_in_y().

Referenced by ranged::execute_shaped_attack(), and projectile_attack().

◆ smash_items()

void map::smash_items ( const tripoint p,
int  power,
const std::string &  cause_message,
bool  do_destroy 
)

Tries to smash the items at the given tripoint.

Definition at line 2983 of file map.cpp.

2985{
2986 if( !has_items( p ) ) {
2987 return;
2988 }
2989
2990 // Keep track of how many items have been damaged, and what the first one is
2991 int items_damaged = 0;
2992 int items_destroyed = 0;
2993 std::string damaged_item_name;
2994
2995 // TODO: Bullets should be pretty much corpse-only
2996 constexpr const int min_destroy_threshold = 50;
2997
2998 std::vector<item> contents;
2999 map_stack items = i_at( p );
3000 for( auto i = items.begin(); i != items.end(); ) {
3001 // If the power is low or it's not an explosion, only pulp rezing corpses
3002 if( ( power < min_destroy_threshold || !do_destroy ) && !i->can_revive() ) {
3003 i++;
3004 continue;
3005 }
3006
3007 // Active explosives arbitrarily get double the destroy threshold
3008 bool is_active_explosive = i->active && i->type->get_use( "explosion" ) != nullptr;
3009 if( is_active_explosive && i->charges == 0 ) {
3010 i++;
3011 continue;
3012 }
3013
3014 const float material_factor = i->chip_resistance( true );
3015 // Intact non-rezing get a boost
3016 const float intact_mult = 2.0f -
3017 ( static_cast<float>( i->damage_level( i->max_damage() ) ) / i->max_damage() );
3018 const float destroy_threshold = min_destroy_threshold
3019 + material_factor * intact_mult
3020 + ( is_active_explosive ? min_destroy_threshold : 0 );
3021 // For pulping, only consider material resistance. Non-rezing can only be destroyed.
3022 const float pulp_threshold = i->can_revive() ? material_factor : destroy_threshold;
3023 // Active explosives that will explode this turn are indestructible (they are exploding "now")
3024 if( power < pulp_threshold ) {
3025 i++;
3026 continue;
3027 }
3028
3029 bool item_was_destroyed = false;
3030 float destroy_chance = ( power - pulp_threshold ) / 4.0;
3031
3032 const bool by_charges = i->count_by_charges();
3033 if( by_charges ) {
3034 destroy_chance *= i->charges_per_volume( 250_ml );
3035 if( x_in_y( destroy_chance, destroy_threshold ) ) {
3036 item_was_destroyed = true;
3037 }
3038 } else {
3039 const field_type_id type_blood = i->is_corpse() ? i->get_mtype()->bloodType() : fd_null;
3040 float roll = rng_float( 0.0, destroy_chance );
3041 if( roll >= destroy_threshold ) {
3042 item_was_destroyed = true;
3043 } else if( roll >= pulp_threshold ) {
3044 // Only pulp
3045 i->set_damage( i->max_damage() );
3046 // TODO: Blood streak cone away from explosion
3047 add_splash( type_blood, p, 1, destroy_chance );
3048 // If it was the first item to be damaged, note it
3049 if( items_damaged == 0 ) {
3050 damaged_item_name = i->tname();
3051 }
3052 items_damaged++;
3053 }
3054 }
3055
3056 // Remove them if they were damaged too much
3057 if( item_was_destroyed ) {
3058 // But save the contents, except for irremovable gunmods
3059 for( item *elem : i->contents.all_items_top() ) {
3060 if( !elem->is_irremovable() ) {
3061 contents.push_back( item( *elem ) );
3062 }
3063 }
3064
3065 if( items_damaged == 0 ) {
3066 damaged_item_name = i->tname();
3067 }
3068 i = i_rem( p, i );
3069 items_damaged++;
3070 items_destroyed++;
3071 } else {
3072 i++;
3073 }
3074 }
3075
3076 // Let the player know that the item was damaged if they can see it.
3077 if( items_destroyed > 1 && g->u.sees( p ) ) {
3078 add_msg( m_bad, _( "The %s destroys several items!" ), cause_message );
3079 } else if( items_destroyed == 1 && items_damaged == 1 && g->u.sees( p ) ) {
3080 //~ %1$s: the cause of destruction, %2$s: destroyed item name
3081 add_msg( m_bad, _( "The %1$s destroys the %2$s!" ), cause_message, damaged_item_name );
3082 } else if( items_damaged > 1 && g->u.sees( p ) ) {
3083 add_msg( m_bad, _( "The %s damages several items." ), cause_message );
3084 } else if( items_damaged == 1 && g->u.sees( p ) ) {
3085 //~ %1$s: the cause of damage, %2$s: damaged item name
3086 add_msg( m_bad, _( "The %1$s damages the %2$s." ), cause_message, damaged_item_name );
3087 }
3088
3089 for( const item &it : contents ) {
3090 add_item_or_charges( p, it );
3091 }
3092}
void add_splash(const field_type_id &type, const tripoint &center, int radius, int intensity)
Definition: map.cpp:5528

References _, add_item_or_charges(), add_msg(), add_splash(), item_contents::all_items_top(), item_stack::begin(), item::contents, item_stack::end(), fd_null, g, has_items(), i_at(), i_rem(), m_bad, rng_float(), and x_in_y().

Referenced by explosion_handler::do_blast(), explosion_handler::do_blast_new(), move_vehicle(), and shoot().

◆ spawn_an_item() [1/2]

void map::spawn_an_item ( const point p,
item  new_item,
int  charges,
int  damlevel 
)
inline

Definition at line 1311 of file map.h.

1311 {
1312 spawn_an_item( tripoint( p, abs_sub.z ), new_item, charges, damlevel );
1313 }
item & spawn_an_item(const tripoint &p, item new_item, int charges, int damlevel)
Definition: map.cpp:4134

References abs_sub, spawn_an_item(), and tripoint::z.

◆ spawn_an_item() [2/2]

item & map::spawn_an_item ( const tripoint p,
item  new_item,
int  charges,
int  damlevel 
)

Definition at line 4134 of file map.cpp.

4136{
4137 if( charges && new_item.charges > 0 ) {
4138 //let's fail silently if we specify charges for an item that doesn't support it
4139 new_item.charges = charges;
4140 }
4141 new_item = new_item.in_its_container();
4142 if( ( new_item.made_of( LIQUID ) && has_flag( "SWIMMABLE", p ) ) ||
4143 has_flag( "DESTROY_ITEM", p ) ) {
4144 return null_item_reference();
4145 }
4146
4147 new_item.set_damage( damlevel );
4148
4149 return add_item_or_charges( p, new_item );
4150}
item & set_damage(int qty)
Filter setting damage constrained by min_damage and max_damage.
Definition: item.cpp:714
item in_its_container() const
Returns this item into its default container.
Definition: item.cpp:841

References add_item_or_charges(), item::charges, has_flag(), item::in_its_container(), LIQUID, item::made_of(), null_item_reference(), and item::set_damage().

Referenced by salvage_actor::cut_up(), spawn_an_item(), and spawn_item().

◆ spawn_artifact()

void map::spawn_artifact ( const tripoint p)

Definition at line 4173 of file map.cpp.

4174{
4176}
itype_id new_artifact()
Definition: artifact.cpp:677

References add_item_or_charges(), new_artifact(), and calendar::start_of_cataclysm.

Referenced by draw_mine(), and draw_temple().

◆ spawn_item() [1/4]

void map::spawn_item ( const point p,
const itype_id type_id,
unsigned  quantity = 1,
int  charges = 0,
const time_point birthday = calendar::start_of_cataclysm,
int  damlevel = 0 
)
inline

Definition at line 1264 of file map.h.

1266 {
1267 spawn_item( tripoint( p, abs_sub.z ), type_id, quantity, charges, birthday, damlevel );
1268 }

References abs_sub, spawn_item(), and tripoint::z.

◆ spawn_item() [2/4]

void map::spawn_item ( const point p,
const std::string &  type_id,
unsigned  quantity = 1,
int  charges = 0,
const time_point birthday = calendar::start_of_cataclysm,
int  damlevel = 0 
)
inline

Definition at line 1277 of file map.h.

1279 {
1280 spawn_item( tripoint( p, abs_sub.z ), type_id, quantity, charges, birthday, damlevel );
1281 }

References abs_sub, spawn_item(), and tripoint::z.

◆ spawn_item() [3/4]

void map::spawn_item ( const tripoint p,
const itype_id type_id,
unsigned  quantity = 1,
int  charges = 0,
const time_point birthday = calendar::start_of_cataclysm,
int  damlevel = 0 
)

Definition at line 4183 of file map.cpp.

4186{
4187 if( type_id.is_null() ) {
4188 return;
4189 }
4190
4191 if( item_is_blacklisted( type_id ) ) {
4192 return;
4193 }
4194 // recurse to spawn (quantity - 1) items
4195 for( size_t i = 1; i < quantity; i++ ) {
4196 spawn_item( p, type_id, 1, charges, birthday, damlevel );
4197 }
4198 // spawn the item
4199 item new_item( type_id, birthday );
4200 if( one_in( 3 ) && new_item.has_flag( "VARSIZE" ) ) {
4201 new_item.set_flag( "FIT" );
4202 }
4203
4204 spawn_an_item( p, new_item, charges, damlevel );
4205}
bool is_null() const
Returns whether this represents the id of the null-object (in which case it's the null-id).
Definition: string_id.h:317
bool item_is_blacklisted(const itype_id &id)

References item::has_flag(), string_id< T >::is_null(), item_is_blacklisted(), one_in(), item::set_flag(), spawn_an_item(), and spawn_item().

Referenced by computer_session::action_extract_rad_source(), jmapgen_spawn_item::apply(), MapExtras::burned_ground_parser(), talk_function::buy_100_logs(), talk_function::buy_10_logs(), activity_handlers::chop_planks_finish(), create_anomaly(), create_burnproducts(), iexamine::curtains(), MapExtras::dead_vegetation_parser(), game::disable_robot(), construct::done_window_curtains(), draw_lab(), draw_office_tower(), explosion_handler::emp_blast(), iexamine::fertilize_plant(), dig_activity_actor::finish(), iexamine::flower_marloss(), activity_handlers::hacksaw_finish(), vehicle::handle_trap(), make_rubble(), mapgen_cavern(), mapgen_tutorial(), MapExtras::mx_casings(), MapExtras::mx_drugdeal(), MapExtras::mx_grave(), MapExtras::mx_mayhem(), MapExtras::mx_minefield(), MapExtras::mx_roadworks(), om_cutdown_trees(), trap::on_disarmed(), activity_handlers::oxytorch_finish(), pick_plant(), mission_start::place_deposit_box(), MapExtras::place_fumarole(), mission_start::place_priest_diary(), place_vending(), activity_handlers::pry_nails_finish(), mission_start::ranch_nurse_1(), mission_start::ranch_nurse_2(), mission_start::ranch_scavenger_1(), mission_start::ranch_scavenger_2(), mission_start::ranch_scavenger_3(), iexamine::recycle_compactor(), iexamine::shrub_marloss(), sinkhole_safety_roll(), spawn_item(), iexamine::tree_hickory(), iexamine::tree_marloss(), try_remove_bear_trap(), try_remove_heavysnare(), try_remove_lightsnare(), unroll_digging(), and game::vertical_move().

◆ spawn_item() [4/4]

void map::spawn_item ( const tripoint p,
const std::string &  type_id,
unsigned  quantity = 1,
int  charges = 0,
const time_point birthday = calendar::start_of_cataclysm,
int  damlevel = 0 
)
inline

Definition at line 1272 of file map.h.

1274 {
1275 spawn_item( p, itype_id( type_id ), quantity, charges, birthday, damlevel );
1276 }

References itype_id, and spawn_item().

◆ spawn_items() [1/2]

void map::spawn_items ( const point p,
const std::vector< item > &  new_items 
)
inline

Definition at line 1387 of file map.h.

1387 {
1388 spawn_items( tripoint( p, abs_sub.z ), new_items );
1389 }

References abs_sub, spawn_items(), and tripoint::z.

◆ spawn_items() [2/2]

std::vector< item * > map::spawn_items ( const tripoint p,
const std::vector< item > &  new_items 
)

Definition at line 4152 of file map.cpp.

4153{
4154 std::vector<item *> ret;
4155 if( !inbounds( p ) || has_flag( "DESTROY_ITEM", p ) ) {
4156 return ret;
4157 }
4158 const bool swimmable = has_flag( "SWIMMABLE", p );
4159 for( const item &new_item : new_items ) {
4160
4161 if( new_item.made_of( LIQUID ) && swimmable ) {
4162 continue;
4163 }
4164 item &it = add_item_or_charges( p, new_item );
4165 if( !it.is_null() ) {
4166 ret.push_back( &it );
4167 }
4168 }
4169
4170 return ret;
4171}
bool is_null() const
Definition: item.cpp:732

References add_item_or_charges(), has_flag(), inbounds(), item::is_null(), LIQUID, and cata::hash64_detail::ret.

Referenced by jmapgen_loot::apply(), bash_furn_success(), bash_items(), bash_ter_success(), complete_construction(), construct::done_deconstruct(), dig_activity_actor::finish(), dig_channel_activity_actor::finish(), talk_function::loot_building(), MapExtras::mx_casings(), MapExtras::mx_corpses(), process_fields_in_submap(), put_items_from_loc(), veh_utils::repair_part(), smash(), and spawn_items().

◆ spawn_monsters()

void map::spawn_monsters ( bool  ignore_sight)

Spawn monsters from submap spawn points and from the overmap.

Parameters
ignore_sightIf true, monsters may spawn in the view of the player character (useful when the whole map has been loaded instead, e.g. when starting a new game, or after teleportation or after moving vertically). If false, monsters are not spawned in view of player character.

Definition at line 7705 of file map.cpp.

7706{
7707 const int zmin = zlevels ? -OVERMAP_DEPTH : abs_sub.z;
7708 const int zmax = zlevels ? OVERMAP_HEIGHT : abs_sub.z;
7709 tripoint gp;
7710 int &gx = gp.x;
7711 int &gy = gp.y;
7712 int &gz = gp.z;
7713 for( gz = zmin; gz <= zmax; gz++ ) {
7714 for( gx = 0; gx < my_MAPSIZE; gx++ ) {
7715 for( gy = 0; gy < my_MAPSIZE; gy++ ) {
7716 spawn_monsters_submap( gp, ignore_sight );
7717 }
7718 }
7719 }
7720}
void spawn_monsters_submap(const tripoint &gp, bool ignore_sight)
Definition: map.cpp:7650

References abs_sub, my_MAPSIZE, OVERMAP_DEPTH, OVERMAP_HEIGHT, spawn_monsters_submap(), tripoint::x, tripoint::y, tripoint::z, and zlevels.

Referenced by game::do_turn(), editmap::mapgen_preview(), game::place_player_overmap(), game::start_game(), game::update_map(), and game::vertical_shift().

◆ spawn_monsters_submap()

void map::spawn_monsters_submap ( const tripoint gp,
bool  ignore_sight 
)
private

Definition at line 7650 of file map.cpp.

7651{
7652 // Load unloaded monsters
7653 // TODO: fix point types
7655
7656 // Only spawn new monsters after existing monsters are loaded.
7657 // TODO: fix point types
7658 auto groups = overmap_buffer.groups_at( tripoint_abs_sm( gp + abs_sub.xy() ) );
7659 for( auto &mgp : groups ) {
7660 spawn_monsters_submap_group( gp, *mgp, ignore_sight );
7661 }
7662
7663 submap *const current_submap = get_submap_at_grid( gp );
7664 const tripoint gp_ms = sm_to_ms_copy( gp );
7665
7666 for( auto &i : current_submap->spawns ) {
7667 const tripoint center = gp_ms + i.pos;
7669
7670 for( int j = 0; j < i.count; j++ ) {
7671 monster tmp( i.type );
7672 tmp.mission_id = i.mission_id;
7673 if( i.name != "NONE" ) {
7674 tmp.unique_name = i.name;
7675 }
7676 if( i.friendly ) {
7677 tmp.friendly = -1;
7678 }
7679
7680 const auto valid_location = [&]( const tripoint & p ) {
7681 // Checking for creatures via g is only meaningful if this is the main game map.
7682 // If it's some local map instance, the coordinates will most likely not even match.
7683 return ( !g || &get_map() != this || !g->critter_at( p ) ) && tmp.can_move_to( p );
7684 };
7685
7686 const auto place_it = [&]( const tripoint & p ) {
7687 monster *const placed = g->place_critter_at( make_shared_fast<monster>( tmp ), p );
7688 if( placed ) {
7689 placed->on_load();
7690 }
7691 };
7692
7693 // First check out defined spawn location for a valid placement, and if that doesn't work
7694 // then fall back to picking a random point that is a valid location.
7695 if( valid_location( center ) ) {
7696 place_it( center );
7697 } else if( const cata::optional<tripoint> pos = random_point( points, valid_location ) ) {
7698 place_it( *pos );
7699 }
7700 }
7701 }
7702 current_submap->spawns.clear();
7703}
void spawn_monsters_submap_group(const tripoint &gp, mongroup &group, bool ignore_sight)
Definition: map.cpp:7516
void on_load()
Retroactively update monster.
Definition: monster.cpp:3010
std::vector< mongroup * > groups_at(const tripoint_abs_sm &p)
Monster groups at p - absolute submap coordinates.
void spawn_monster(const tripoint_abs_sm &p)
Spawn monsters from the overmap onto the main map (game::m).

References abs_sub, monster::can_move_to(), center, monster::friendly, g, get_map(), get_submap_at_grid(), overmapbuffer::groups_at(), monster::mission_id, monster::on_load(), overmap_buffer, points_in_radius(), random_point(), sm_to_ms_copy(), overmapbuffer::spawn_monster(), spawn_monsters_submap_group(), submap::spawns, monster::unique_name, and tripoint::xy().

Referenced by spawn_monsters().

◆ spawn_monsters_submap_group()

void map::spawn_monsters_submap_group ( const tripoint gp,
mongroup group,
bool  ignore_sight 
)
private

Definition at line 7516 of file map.cpp.

7517{
7518 const int s_range = std::min( HALF_MAPSIZE_X,
7519 g->u.sight_range( g->light_level( g->u.posz() ) ) );
7520 int pop = group.population;
7521 std::vector<tripoint> locations;
7522 if( !ignore_sight ) {
7523 // If the submap is one of the outermost submaps, assume that monsters are
7524 // invisible there.
7525 if( gp.x == 0 || gp.y == 0 || gp.x + 1 == MAPSIZE || gp.y + 1 == MAPSIZE ) {
7526 ignore_sight = true;
7527 }
7528 }
7529
7530 if( gp.z != g->u.posz() ) {
7531 // Note: this is only OK because 3D vision isn't a thing yet
7532 ignore_sight = true;
7533 }
7534
7535 static const auto allow_on_terrain = [&]( const tripoint & p ) {
7536 // TODO: flying creatures should be allowed to spawn without a floor,
7537 // but the new creature is created *after* determining the terrain, so
7538 // we can't check for it here.
7539 return passable( p ) && has_floor( p );
7540 };
7541
7542 // If the submap is uniform, we can skip many checks
7543 const submap *current_submap = get_submap_at_grid( gp );
7544 bool ignore_terrain_checks = false;
7545 bool ignore_inside_checks = gp.z < 0;
7546 if( current_submap->is_uniform ) {
7547 const tripoint upper_left{ SEEX * gp.x, SEEY * gp.y, gp.z };
7548 if( !allow_on_terrain( upper_left ) ||
7549 ( !ignore_inside_checks && has_flag_ter_or_furn( TFLAG_INDOORS, upper_left ) ) ) {
7550 const tripoint glp = getabs( gp );
7551 dbg( DL::Warn ) << "Empty locations for group " << group.type.str()
7552 << " at uniform submap " << gp << " global " << glp;
7553 return;
7554 }
7555
7556 ignore_terrain_checks = true;
7557 ignore_inside_checks = true;
7558 }
7559
7560 for( int x = 0; x < SEEX; ++x ) {
7561 for( int y = 0; y < SEEY; ++y ) {
7562 int fx = x + SEEX * gp.x;
7563 int fy = y + SEEY * gp.y;
7564 tripoint fp{ fx, fy, gp.z };
7565 if( g->critter_at( fp ) != nullptr ) {
7566 continue; // there is already some creature
7567 }
7568
7569 if( !ignore_terrain_checks && !allow_on_terrain( fp ) ) {
7570 continue; // solid area, impassable
7571 }
7572
7573 if( !ignore_sight && sees( g->u.pos(), fp, s_range ) ) {
7574 continue; // monster must spawn outside the viewing range of the player
7575 }
7576
7577 if( !ignore_inside_checks && has_flag_ter_or_furn( TFLAG_INDOORS, fp ) ) {
7578 continue; // monster must spawn outside.
7579 }
7580
7581 locations.push_back( fp );
7582 }
7583 }
7584
7585 if( locations.empty() ) {
7586 // TODO: what now? there is no possible place to spawn monsters, most
7587 // likely because the player can see all the places.
7588 const tripoint glp = getabs( gp );
7589 dbg( DL::Warn ) << "Empty locations for group " << group.type.str()
7590 << " at " << gp << " global " << glp;
7591 // Just kill the group. It's not like we're removing existing monsters
7592 // Unless it's a horde - then don't kill it and let it spawn behind a tree or smoke cloud
7593 if( !group.horde ) {
7594 group.clear();
7595 }
7596
7597 return;
7598 }
7599
7600 if( pop ) {
7601 // Populate the group from its population variable.
7602 for( int m = 0; m < pop; m++ ) {
7604 if( !spawn_details.name ) {
7605 continue;
7606 }
7607 monster tmp( spawn_details.name );
7608
7609 // If a monster came from a horde population, configure them to always be willing to rejoin a horde.
7610 if( group.horde ) {
7611 tmp.set_horde_attraction( MHA_ALWAYS );
7612 }
7613 for( int i = 0; i < spawn_details.pack_size; i++ ) {
7614 group.monsters.push_back( tmp );
7615 }
7616 }
7617 }
7618
7619 // Find horde's target submap
7620 // TODO: fix point types
7621 tripoint horde_target( tripoint( -abs_sub.xy(), abs_sub.z ) + group.target.xy().raw() );
7622 sm_to_ms( horde_target );
7623 for( auto &tmp : group.monsters ) {
7624 for( int tries = 0; tries < 10 && !locations.empty(); tries++ ) {
7626 if( !tmp.can_move_to( p ) ) {
7627 continue; // target can not contain the monster
7628 }
7629 if( group.horde ) {
7630 // Give monster a random point near horde's expected destination
7631 const tripoint rand_dest = horde_target +
7632 point( rng( 0, SEEX ), rng( 0, SEEY ) );
7633 const int turns = rl_dist( p, rand_dest ) + group.interest;
7634 tmp.wander_to( rand_dest, turns );
7635 add_msg( m_debug, "%s targeting %d,%d,%d", tmp.disp_name(),
7636 tmp.wander_pos.x, tmp.wander_pos.y, tmp.wander_pos.z );
7637 }
7638
7639 monster *const placed = g->place_critter_at( make_shared_fast<monster>( tmp ), p );
7640 if( placed ) {
7641 placed->on_load();
7642 }
7643 break;
7644 }
7645 }
7646 // indicates the group is empty, and can be removed later
7647 group.clear();
7648}
void sm_to_ms(int &x, int &y)
static constexpr int HALF_MAPSIZE_X
@ MHA_ALWAYS
Definition: monster.h:76
generic_factory< overmap_location > locations("overmap location")

References abs_sub, add_msg(), dbg, g, get_submap_at_grid(), getabs(), MonsterGroupManager::GetResultFromGroup(), HALF_MAPSIZE_X, has_flag_ter_or_furn(), has_floor(), submap::is_uniform, anonymous_namespace{overmap_location.cpp}::locations, m_debug, MAPSIZE, MHA_ALWAYS, MonsterGroupResult::name, monster::on_load(), MonsterGroupResult::pack_size, passable(), random_entry_removed(), rl_dist(), rng(), sees(), SEEX, SEEY, monster::set_horde_attraction(), sm_to_ms(), TFLAG_INDOORS, Warn, tripoint::x, tripoint::xy(), tripoint::y, and tripoint::z.

Referenced by spawn_monsters_submap().

◆ spawn_natural_artifact()

void map::spawn_natural_artifact ( const tripoint p,
artifact_natural_property  prop 
)

Definition at line 4178 of file map.cpp.

4179{
4181}
itype_id new_natural_artifact(artifact_natural_property prop)
Definition: artifact.cpp:931

References add_item_or_charges(), new_natural_artifact(), and calendar::start_of_cataclysm.

Referenced by debug_menu::debug(), and MapExtras::mx_portal_in().

◆ spread_gas()

void map::spread_gas ( field_entry cur,
const tripoint p,
int  percent_spread,
const time_duration outdoor_age_speedup,
scent_block sblk 
)
private

Definition at line 251 of file map_field.cpp.

253{
254 map &here = get_map();
255 // TODO: fix point types
256 const oter_id &cur_om_ter =
258 const bool sheltered = g->is_sheltered( p );
260 const int winddirection = weather.winddirection;
261 const int windpower = get_local_windpower( weather.windspeed, cur_om_ter, p, winddirection,
262 sheltered );
263
264 const int current_intensity = cur.get_field_intensity();
265 const field_type_id ft_id = cur.get_field_type();
266
267 const int scent_neutralize = ft_id->get_intensity_level( current_intensity -
269
270 if( scent_neutralize > 0 ) {
271 // modify scents by neutralization value (minus)
272 for( const tripoint &tmp : points_in_radius( p, 1 ) ) {
273 sblk.apply_gas( tmp, scent_neutralize );
274 }
275 }
276
277 // Dissipate faster outdoors.
278 if( is_outside( p ) ) {
279 const time_duration current_age = cur.get_field_age();
280 cur.set_field_age( current_age + outdoor_age_speedup );
281 }
282
283 // Bail out if we don't meet the spread chance or required intensity.
284 if( current_intensity <= 1 || rng( 1, 100 - windpower ) > percent_spread ) {
285 return;
286 }
287
288 // First check if we can fall
289 // TODO: Make fall and rise chances parameters to enable heavy/light gas
290 if( zlevels && p.z > -OVERMAP_DEPTH ) {
291 const tripoint down{ p.xy(), p.z - 1 };
292 if( gas_can_spread_to( cur, p, down ) && valid_move( p, down, true, true ) ) {
293 maptile down_tile = maptile_at_internal( down );
294 gas_spread_to( cur, down_tile, down );
295 return;
296 }
297 }
298
299 auto neighs = get_neighbors( p );
300 size_t end_it = static_cast<size_t>( rng( 0, neighs.size() - 1 ) );
301 std::vector<size_t> spread;
302 std::vector<size_t> neighbour_vec;
303 // Then, spread to a nearby point.
304 // If not possible (or randomly), try to spread up
305 // Wind direction will block the field spreading into the wind.
306 // Start at end_it + 1, then wrap around until all elements have been processed.
307 for( size_t i = ( end_it + 1 ) % neighs.size(), count = 0;
308 count != neighs.size();
309 i = ( i + 1 ) % neighs.size(), count++ ) {
310 const auto &neigh = neighs[i];
311 if( gas_can_spread_to( cur, p, neigh.first ) ) {
312 spread.push_back( i );
313 }
314 }
315 auto maptiles = get_wind_blockers( winddirection, p );
316 // Three map tiles that are facing the wind direction.
317 const maptile remove_tile = std::get<0>( maptiles );
318 const maptile remove_tile2 = std::get<1>( maptiles );
319 const maptile remove_tile3 = std::get<2>( maptiles );
320 if( !spread.empty() && ( !zlevels || one_in( spread.size() ) ) ) {
321 // Construct the destination from offset and p
322 if( g->is_sheltered( p ) || windpower < 5 ) {
323 std::pair<tripoint, maptile> &n = neighs[ random_entry( spread ) ];
324 gas_spread_to( cur, n.second, n.first );
325 } else {
326 end_it = static_cast<size_t>( rng( 0, neighs.size() - 1 ) );
327 // Start at end_it + 1, then wrap around until all elements have been processed.
328 for( size_t i = ( end_it + 1 ) % neighs.size(), count = 0;
329 count != neighs.size();
330 i = ( i + 1 ) % neighs.size(), count++ ) {
331 const auto &neigh = neighs[i].second;
332 if( ( neigh.pos_.x != remove_tile.pos_.x && neigh.pos_.y != remove_tile.pos_.y ) ||
333 ( neigh.pos_.x != remove_tile2.pos_.x && neigh.pos_.y != remove_tile2.pos_.y ) ||
334 ( neigh.pos_.x != remove_tile3.pos_.x && neigh.pos_.y != remove_tile3.pos_.y ) ) {
335 neighbour_vec.push_back( i );
336 } else if( x_in_y( 1, std::max( 2, windpower ) ) ) {
337 neighbour_vec.push_back( i );
338 }
339 }
340 if( !neighbour_vec.empty() ) {
341 std::pair<tripoint, maptile> &n = neighs[neighbour_vec[rng( 0, neighbour_vec.size() - 1 )]];
342 gas_spread_to( cur, n.second, n.first );
343 }
344 }
345 } else if( zlevels && p.z < OVERMAP_HEIGHT ) {
346 const tripoint up{ p.xy(), p.z + 1 };
347 if( gas_can_spread_to( cur, p, up ) && valid_move( p, up, true, true ) ) {
348 maptile up_tile = maptile_at_internal( up );
349 gas_spread_to( cur, up_tile, up );
350 }
351 }
352}
std::tuple< maptile, maptile, maptile > get_wind_blockers(const int &winddirection, const tripoint &pos)
Definition: map_field.cpp:1894
bool gas_can_spread_to(field_entry &cur, const tripoint &src, const tripoint &dst)
Definition: map_field.cpp:211
void gas_spread_to(field_entry &cur, maptile &dst, const tripoint &p)
Definition: map_field.cpp:225
coords::coord_point< tripoint, coords::origin::abs, coords::omt > tripoint_abs_omt
Definition: coordinates.h:493
double get_local_windpower(double windpower, const oter_id &omter, const tripoint &location, const int &winddirection, bool sheltered)
Definition: weather.cpp:938
const field_intensity_level & get_intensity_level(int level=0) const
Definition: field_type.cpp:130
point pos_
Definition: submap.h:272
void apply_gas(const tripoint &p, const int nintensity=0)
Definition: scent_block.h:77

References scent_block::apply_gas(), detail::count(), g, gas_can_spread_to(), gas_spread_to(), field_entry::get_field_age(), field_entry::get_field_intensity(), field_entry::get_field_type(), field_type::get_intensity_level(), get_local_windpower(), get_map(), get_neighbors(), get_weather(), get_wind_blockers(), getabs(), is_outside(), maptile_at_internal(), ms_to_omt_copy(), one_in(), overmap_buffer, OVERMAP_DEPTH, OVERMAP_HEIGHT, points_in_radius(), maptile::pos_, random_entry(), rng(), field_intensity_level::scent_neutralization, field_entry::set_field_age(), overmapbuffer::ter(), valid_move(), point::x, x_in_y(), tripoint::xy(), point::y, tripoint::z, and zlevels.

Referenced by process_fields_in_submap().

◆ stored_volume()

units::volume map::stored_volume ( const tripoint p)

Definition at line 4213 of file map.cpp.

4214{
4215 return i_at( p ).stored_volume();
4216}
units::volume stored_volume() const
Total volume of the items here.
Definition: item_stack.cpp:98

References i_at(), and item_stack::stored_volume().

◆ support_dirty()

void map::support_dirty ( const tripoint p)
private

Definition at line 2267 of file map.cpp.

2268{
2269 if( zlevels ) {
2270 support_cache_dirty.insert( p );
2271 }
2272}

References support_cache_dirty, and zlevels.

Referenced by add_field(), add_item_or_charges(), drop_furniture(), furn_set(), ter_set(), and update_suspension_cache().

◆ supports_above()

bool map::supports_above ( const tripoint p) const

Does this tile support vehicles and furniture above it.

Definition at line 2020 of file map.cpp.

2021{
2022 const maptile tile = maptile_at( p );
2023 const ter_t &ter = tile.get_ter_t();
2024 if( ter.movecost == 0 ) {
2025 return true;
2026 }
2027
2028 const furn_id frn_id = tile.get_furn();
2029 if( frn_id != f_null ) {
2030 const furn_t &frn = frn_id.obj();
2031 if( frn.movecost < 0 ) {
2032 return true;
2033 }
2034 }
2035
2036 return veh_at( p ).has_value();
2037}
constexpr bool has_value() const noexcept
Definition: optional.h:123
furn_id get_furn() const
Definition: submap.h:285

References f_null, maptile::get_furn(), maptile::get_ter_t(), cata::optional< T >::has_value(), maptile_at(), map_data_common_t::movecost, int_id< T >::obj(), ter(), and veh_at().

Referenced by vehicle::check_falling_or_floating(), and drop_furniture().

◆ ter() [1/2]

ter_id map::ter ( const point p) const
inline

Definition at line 881 of file map.h.

881 {
882 return ter( tripoint( p, abs_sub.z ) );
883 }

References abs_sub, ter(), and tripoint::z.

◆ ter() [2/2]

ter_id map::ter ( const tripoint p) const

Definition at line 1498 of file map.cpp.

1499{
1500 if( !inbounds( p ) ) {
1501 return t_null;
1502 }
1503
1504 point l;
1505 submap *const current_submap = get_submap_at( p, l );
1506
1507 return current_submap->get_ter( l );
1508}

References get_submap_at(), submap::get_ter(), inbounds(), and t_null.

Referenced by computer_session::action_conveyor(), computer_session::action_data_anal(), computer_session::action_deactivate_shock_vent(), computer_session::action_elevator_on(), computer_session::action_extract_rad_source(), computer_session::action_geiger(), computer_session::action_irradiator(), computer_session::action_sample(), computer_session::action_srcf_elevator(), computer_session::action_srcf_seal(), actualize(), ter_furn_transform::add_all_messages(), add_boardable(), apply< ter_t >(), cata_event_dispatch::avatar_moves(), bash_rating(), bash_resistance(), bash_strength(), bash_ter_furn(), bash_ter_success(), board_up(), MapExtras::burned_ground_parser(), activity_handlers::burrow_finish(), can_construct(), can_do_activity_there(), can_examine_at(), iexamine::cardreader(), iexamine::cardreader_foodplace(), construct::check_deconstruct(), vehicle::autodrive_controller::check_drivable(), activity_handlers::chop_logs_finish(), chop_tree_activity(), close_door(), complete_construction(), coverage(), iexamine::curtains(), MapExtras::dead_vegetation_parser(), determine_wall_corner(), displace_water(), construct::done_deconstruct(), construct::done_digormine_stair(), construct::done_extract_maybe_revert_to_dirt(), construct::done_mine_upstair(), editmap_hilight::draw(), draw_connections(), draw_lab(), editmap::draw_main_ui_overlay(), draw_mine(), draw_temple(), draw_triffid(), avatar_action::eat_here(), explosion_handler::emp_blast(), examine(), game::examine(), game::extended_description(), computer_session::failure_destroy_data(), computer_session::failure_pump_explode(), computer_session::failure_pump_leak(), feature< ter_id >(), talk_function::field_plant(), activity_handlers::fill_liquid_do_turn(), activity_handlers::fill_pit_finish(), find_base_construction(), game::find_or_make_stairs(), find_potential_computer_point(), dig_activity_actor::finish(), dig_channel_activity_actor::finish(), hacking_activity_actor::finish(), Character::floor_bedding_warmth(), fromPumpFuel(), iexamine::fswitch(), gas_can_spread_to(), generic_multi_activity_locations(), get_changed_ids_from_update(), get_hack_type(), get_harvest(), get_harvest_names(), get_known_connections(), get_roof(), get_ter_transforms_into(), iexamine::getGasPumpByNumber(), iexamine::getNearFilledGasTank(), getNearPumpCount(), activity_handlers::hacksaw_finish(), has_flag_ter(), has_neighbor(), has_pre_terrain(), hit_with_acid(), advanced_inv_area::init(), is_bashable(), is_bashable_ter(), anonymous_namespace{gates.cpp}::gate_data::is_suitable_wall(), is_suspension_valid(), iexamine::ledge(), talk_function::loot_building(), mapgen_ants_generic(), mapgen_lake_shore(), fungal_effects::marlossify(), map_stack::max_volume(), map_funcs::migo_nerve_cage_removal(), avatar_action::move(), move_cost(), move_vehicle(), MapExtras::mx_grove(), MapExtras::mx_helicopter(), MapExtras::mx_house_spider(), MapExtras::mx_house_wasp(), MapExtras::mx_portal_in(), MapExtras::mx_shrubbery(), iexamine::nanofab(), obstacle_coverage(), om_cutdown_trees(), om_harvest_ter(), open(), open_door(), activity_handlers::oxytorch_finish(), iexamine::pedestal_wyrm(), tutorial_game::per_turn(), activity_handlers::pickaxe_finish(), iexamine::pit(), iexamine::pit_covered(), mission_start::place_deposit_box(), place_items(), game::place_player(), game::print_fields_info(), game::print_graffiti_info(), game::print_terrain_info(), process_fields_in_submap(), process_items_in_submap(), produce_sap(), activity_handlers::pry_nails_finish(), rad_scorch(), resolve_regional_terrain_and_furniture(), restock_fruits(), mission_start::reveal_lab_train_depot(), shoot(), supports_above(), ter(), tername(), gates::toggle_gate(), iexamine::toPumpFuel(), ter_furn_transform::transform(), translate(), translate_radius(), trap_set(), turnOnSelectedPump(), Character::update_bodytemp(), update_suspension_cache(), editmap::update_view_with_help(), vehicle_wheel_traction(), game::vertical_move(), game::walk_move(), and water_from().

◆ ter_set() [1/2]

bool map::ter_set ( const point p,
const ter_id new_terrain 
)
inline

Definition at line 906 of file map.h.

906 {
907 return ter_set( tripoint( p, abs_sub.z ), new_terrain );
908 }

References abs_sub, ter_set(), and tripoint::z.

◆ ter_set() [2/2]

bool map::ter_set ( const tripoint p,
const ter_id new_terrain 
)

Definition at line 1639 of file map.cpp.

1640{
1641 if( !inbounds( p ) ) {
1642 return false;
1643 }
1644
1645 point l;
1646 submap *const current_submap = get_submap_at( p, l );
1647 const ter_id old_id = current_submap->get_ter( l );
1648 if( old_id == new_terrain ) {
1649 // Nothing changed
1650 return false;
1651 }
1652
1653 current_submap->set_ter( l, new_terrain );
1654
1655 // Set the dirty flags
1656 const ter_t &old_t = old_id.obj();
1657 const ter_t &new_t = new_terrain.obj();
1658
1659 // HACK: Hack around ledges in traplocs or else it gets NASTY in z-level mode
1660 if( old_t.trap != tr_null && old_t.trap != tr_ledge ) {
1661 auto &traps = traplocs[old_t.trap.to_i()];
1662 const auto iter = std::find( traps.begin(), traps.end(), p );
1663 if( iter != traps.end() ) {
1664 traps.erase( iter );
1665 }
1666 }
1667 if( new_t.trap != tr_null && new_t.trap != tr_ledge ) {
1668 traplocs[new_t.trap.to_i()].push_back( p );
1669 }
1670
1671 if( old_t.transparent != new_t.transparent ) {
1674 }
1675
1676 if( old_t.has_flag( TFLAG_INDOORS ) != new_t.has_flag( TFLAG_INDOORS ) ) {
1678 }
1679
1680 if( new_t.has_flag( TFLAG_NO_FLOOR ) != old_t.has_flag( TFLAG_NO_FLOOR ) ) {
1682 // It's a set, not a flag
1683 support_cache_dirty.insert( p );
1685 }
1686
1687 if( new_t.has_flag( TFLAG_SUSPENDED ) != old_t.has_flag( TFLAG_SUSPENDED ) ) {
1689 if( new_t.has_flag( TFLAG_SUSPENDED ) ) {
1690 level_cache &ch = get_cache( p.z );
1691 ch.suspension_cache.emplace_back( getabs( p ).xy() );
1692 }
1693 }
1694
1696
1698
1699 // TODO: Limit to changes that affect move cost, traps and stairs
1701
1702 tripoint above( p.xy(), p.z + 1 );
1703 // Make sure that if we supported something and no longer do so, it falls down
1704 support_dirty( above );
1705
1706 return true;
1707}
std::list< point > suspension_cache
Definition: map.h:312
trap_id trap
Definition: mapdata.h:469

References detail::find(), get_cache(), get_submap_at(), submap::get_ter(), getabs(), map_data_common_t::has_flag(), inbounds(), invalidate_max_populated_zlev(), int_id< T >::obj(), set_floor_cache_dirty(), set_memory_seen_cache_dirty(), set_outside_cache_dirty(), set_pathfinding_cache_dirty(), set_seen_cache_dirty(), set_suspension_cache_dirty(), submap::set_ter(), set_transparency_cache_dirty(), support_cache_dirty, support_dirty(), level_cache::suspension_cache, TFLAG_INDOORS, TFLAG_NO_FLOOR, TFLAG_SUSPENDED, int_id< T >::to_i(), tr_ledge, tr_null, map_data_common_t::transparent, ter_t::trap, traplocs, tripoint::xy(), and tripoint::z.

Referenced by computer_session::action_elevator_on(), computer_session::action_srcf_elevator(), add_computer(), jmapgen_terrain::apply(), jmapgen_computer::apply(), jmapgen_setmap::apply(), apply< ter_t >(), bash_ter_success(), board_up(), MapExtras::burned_ground_parser(), iexamine::cardreader(), iexamine::cardreader_foodplace(), iexamine::cardreader_robofac(), activity_handlers::chop_logs_finish(), activity_handlers::chop_tree_finish(), activity_handlers::churn_finish(), close_door(), collapse_at(), collapse_invalid_suspension(), complete_construction(), iexamine::curtains(), MapExtras::dead_vegetation_parser(), displace_water(), construct::done_deconstruct(), construct::done_digormine_stair(), construct::done_extract_maybe_revert_to_dirt(), construct::done_mine_upstair(), construct::done_ramp_high(), construct::done_ramp_low(), construct::done_wood_stairs(), draw_anthill(), draw_circle_ter(), draw_connections(), draw_lab(), draw_line_ter(), draw_mine(), draw_rough_circle_ter(), draw_slimepit(), draw_square_ter(), draw_temple(), draw_triffid(), avatar_action::eat_here(), explosion_handler::emp_blast(), computer_session::failure_pump_leak(), computer_session::failure_shutdown(), farm_action(), talk_function::field_harvest(), activity_handlers::fill_pit_finish(), dig_activity_actor::finish(), dig_channel_activity_actor::finish(), hacking_activity_actor::finish(), activity_handlers::forage_finish(), game::forced_door_closing(), mapgen_function_json_base::formatted_set_incredibly_simple(), mapf::formatted_set_simple(), fromPumpFuel(), iexamine::fswitch(), activity_handlers::hacksaw_finish(), iexamine::harvest_plant(), iexamine::harvest_ter(), iexamine::harvest_ter_nectar(), hit_with_acid(), talk_function::loot_building(), make_rubble(), mapgen_ants_curved(), mapgen_ants_four_way(), mapgen_ants_generic(), mapgen_ants_straight(), mapgen_ants_tee(), mapgen_cavern(), mapgen_crater(), mapgen_field(), mapgen_forest_trail_curved(), mapgen_forest_trail_four_way(), mapgen_forest_trail_straight(), mapgen_forest_trail_tee(), mapgen_hellmouth(), mapgen_highway(), mapgen_hive(), mapgen_lake_shore(), mapgen_null(), mapgen_parking_lot(), mapgen_rift(), mapgen_river_curved(), mapgen_river_curved_not(), mapgen_river_straight(), mapgen_road(), mapgen_rock_partial(), mapgen_sewer_curved(), mapgen_sewer_four_way(), mapgen_sewer_straight(), mapgen_sewer_tee(), mapgen_test(), mapgen_tutorial(), fungal_effects::marlossify(), map_funcs::migo_nerve_cage_removal(), move_vehicle(), MapExtras::mx_bandits_block(), MapExtras::mx_clay_deposit(), MapExtras::mx_clearcut(), MapExtras::mx_grave(), MapExtras::mx_grove(), MapExtras::mx_helicopter(), MapExtras::mx_house_wasp(), MapExtras::mx_pond(), MapExtras::mx_portal_in(), MapExtras::mx_roadblock(), MapExtras::mx_shrubbery(), MapExtras::mx_spider(), om_cutdown_trees(), om_harvest_ter(), om_set_hide_site(), open_door(), activity_handlers::oxytorch_finish(), iexamine::pedestal_temple(), iexamine::pedestal_wyrm(), pick_plant(), iexamine::pit(), iexamine::pit_covered(), MapExtras::place_fumarole(), place_gas_pump(), mission_start::place_npc_software(), process_fields_in_submap(), activity_handlers::pry_nails_finish(), rad_scorch(), mission_start::ranch_nurse_4(), mission_start::ranch_nurse_5(), mission_start::ranch_scavenger_2(), mission_start::ranch_scavenger_3(), resolve_regional_terrain_and_furniture(), restock_fruits(), science_room(), set(), iexamine::shrub_marloss(), fungal_effects::spread_fungus_one_tile(), ter_or_furn_set(), ter_set(), gates::toggle_gate(), iexamine::toPumpFuel(), ter_furn_transform::transform(), translate(), translate_radius(), iexamine::tree_hickory(), iexamine::tree_maple(), iexamine::tree_maple_tapped(), iexamine::tree_marloss(), turnOnSelectedPump(), and game::vertical_move().

◆ tername() [1/2]

std::string map::tername ( const point p) const
inline

Definition at line 911 of file map.h.

911 {
912 return tername( tripoint( p, abs_sub.z ) );
913 }

References abs_sub, tername(), and tripoint::z.

◆ tername() [2/2]

◆ tinder_at()

bool map::tinder_at ( const tripoint p)

Checks if there are any tinder flagged items on the tile.

Parameters
ptile to check

Definition at line 2615 of file map.cpp.

2616{
2617 for( const auto &i : i_at( p ) ) {
2618 if( i.has_flag( "TINDER" ) ) {
2619 return true;
2620 }
2621 }
2622 return false;
2623}

References i_at().

Referenced by activity_handlers::start_fire_do_turn().

◆ tr_at()

◆ translate()

void map::translate ( const ter_id from,
const ter_id to 
)

Definition at line 3922 of file map.cpp.

3923{
3924 if( from == to ) {
3925 debugmsg( "map::translate %s => %s",
3926 from.obj().name(),
3927 from.obj().name() );
3928 return;
3929 }
3930 for( const tripoint &p : points_on_zlevel() ) {
3931 if( ter( p ) == from ) {
3932 ter_set( p, to );
3933 }
3934 }
3935}

References debugmsg, map_data_common_t::name(), int_id< T >::obj(), points_on_zlevel(), ter(), and ter_set().

Referenced by jmapgen_translate::apply(), mapgen_lake_shore(), start_location::prepare_map(), mission_start::ranch_nurse_5(), mission_start::ranch_nurse_6(), mission_start::ranch_nurse_7(), mission_start::ranch_nurse_8(), and mission_start::ranch_scavenger_3().

◆ translate_radius()

void map::translate_radius ( const ter_id from,
const ter_id to,
float  radi,
const tripoint p,
bool  same_submap = false,
bool  toggle_between = false 
)

Definition at line 3938 of file map.cpp.

3940{
3941 if( from == to ) {
3942 debugmsg( "map::translate %s => %s", from.obj().name(), to.obj().name() );
3943 return;
3944 }
3945
3946 const tripoint abs_omt_p = ms_to_omt_copy( getabs( p ) );
3947 for( const tripoint &t : points_on_zlevel() ) {
3948 const tripoint abs_omt_t = ms_to_omt_copy( getabs( t ) );
3949 const float radiX = trig_dist( p, t );
3950 if( ter( t ) == from ) {
3951 // within distance, and either no submap limitation or same overmap coords.
3952 if( radiX <= radi && ( !same_submap || abs_omt_t == abs_omt_p ) ) {
3953 ter_set( t, to );
3954 }
3955 } else if( toggle_between && ter( t ) == to ) {
3956 if( radiX <= radi && ( !same_submap || abs_omt_t == abs_omt_p ) ) {
3957 ter_set( t, from );
3958 }
3959 }
3960 }
3961}

References debugmsg, getabs(), ms_to_omt_copy(), map_data_common_t::name(), int_id< T >::obj(), points_on_zlevel(), ter(), ter_set(), and trig_dist().

Referenced by computer_session::action_extract_rad_source(), computer_session::action_irradiator(), computer_session::action_lock(), computer_session::action_open(), computer_session::action_release(), computer_session::action_release_bionics(), computer_session::action_shutters(), and computer_session::action_unlock().

◆ trap_locations()

const std::vector< tripoint > & map::trap_locations ( const trap_id type) const

Definition at line 7751 of file map.cpp.

7752{
7753 return traplocs[type.to_i()];
7754}

References traplocs, and type.

◆ trap_set()

void map::trap_set ( const tripoint p,
const trap_id type 
)

Definition at line 5177 of file map.cpp.

5178{
5179 if( !inbounds( p ) ) {
5180 return;
5181 }
5182
5183 point l;
5184 submap *const current_submap = get_submap_at( p, l );
5185 const ter_t &ter = current_submap->get_ter( l ).obj();
5186 if( ter.trap != tr_null ) {
5187 debugmsg( "set trap %s on top of terrain %s which already has a builit-in trap",
5188 type.obj().name(), ter.name() );
5189 return;
5190 }
5191
5192 // If there was already a trap here, remove it.
5193 if( current_submap->get_trap( l ) != tr_null ) {
5194 remove_trap( p );
5195 }
5196
5197 current_submap->set_trap( l, type );
5198 if( type != tr_null ) {
5199 traplocs[type.to_i()].push_back( p );
5200 }
5201}
void remove_trap(const tripoint &p)
Definition: map.cpp:5261

References debugmsg, get_submap_at(), submap::get_ter(), submap::get_trap(), inbounds(), int_id< T >::obj(), remove_trap(), submap::set_trap(), ter(), tr_null, traplocs, and type.

Referenced by jmapgen_trap::apply(), apply< trap >(), construction_activity(), construct::done_mark_firewood(), construct::done_mark_practice_target(), draw_lab(), vehicle::handle_trap(), mtrap_set(), MapExtras::mx_portal(), place_and_add_as_known(), place_construction(), and explosion_handler::explosion_funcs::resonance_cascade().

◆ unboard_vehicle() [1/2]

void map::unboard_vehicle ( const tripoint p,
bool  dead_passenger = false 
)

Definition at line 1101 of file map.cpp.

1102{
1104 player *passenger = nullptr;
1105 if( !vp ) {
1106 debugmsg( "map::unboard_vehicle: vehicle not found" );
1107 // Try and force unboard the player anyway.
1108 passenger = g->critter_at<player>( p );
1109 if( passenger ) {
1110 passenger->in_vehicle = false;
1111 passenger->controlling_vehicle = false;
1112 }
1113 return;
1114 }
1115 passenger = vp->get_passenger();
1116 unboard_vehicle( *vp, passenger, dead_passenger );
1117}
bool controlling_vehicle
Definition: character.h:228

References Character::controlling_vehicle, debugmsg, g, Character::in_vehicle, optional_vpart_position::part_with_feature(), unboard_vehicle(), veh_at(), and VPFLAG_BOARDABLE.

◆ unboard_vehicle() [2/2]

void map::unboard_vehicle ( const vpart_reference vp,
Character passenger,
bool  dead_passenger = false 
)

Definition at line 1081 of file map.cpp.

1082{
1083 // Mark the part as un-occupied regardless of whether there's a live passenger here.
1085 vp.vehicle().invalidate_mass();
1086
1087 if( !passenger ) {
1088 if( !dead_passenger ) {
1089 debugmsg( "map::unboard_vehicle: passenger not found" );
1090 }
1091 return;
1092 }
1093 passenger->in_vehicle = false;
1094 // Only make vehicle go out of control if the driver is the one unboarding.
1095 if( passenger->controlling_vehicle ) {
1096 vp.vehicle().skidding = true;
1097 }
1098 passenger->controlling_vehicle = false;
1099}
void invalidate_mass()
Mark mass caches and pivot cache as dirty.
Definition: vehicle.cpp:6968
vehicle_part & part() const
Yields the vehicle_part object referenced by this.
Definition: vehicle.cpp:6771
::vehicle & vehicle() const

References Character::controlling_vehicle, debugmsg, Character::in_vehicle, vehicle::invalidate_mass(), vpart_reference::part(), vehicle_part::passenger_flag, vehicle_part::remove_flag(), vehicle::skidding, and vpart_reference::vehicle().

Referenced by board_vehicle(), iexamine::chainfence(), detach_vehicle(), game::fling_creature(), talk_function::individual_mission(), game::is_game_over(), npc::move_to(), game::moving_vehicle_dismount(), game::phasing_move(), game::place_player(), game::place_player_overmap(), mattack::ranged_pull(), shake_vehicle(), game::swap_critters(), avatar_action::swim(), unboard_vehicle(), and game::vertical_move().

◆ update_lum()

void map::update_lum ( item_location loc,
bool  add 
)

Update luminosity before and after item's transformation.

Definition at line 4436 of file map.cpp.

4437{
4438 item *target = loc.get_item();
4439
4440 // if the item is not emissive, do nothing
4441 if( !target->is_emissive() ) {
4442 return;
4443 }
4444
4445 point l;
4446 submap *const current_submap = get_submap_at( loc.position(), l );
4447
4448 if( add ) {
4449 current_submap->update_lum_add( l, *target );
4450 } else {
4451 current_submap->update_lum_rem( l, *target );
4452 }
4453}
bool is_emissive() const
Whether the item emits any light at all.
Definition: item.cpp:6814

References om_direction::add(), item_location::get_item(), get_submap_at(), item::is_emissive(), item_location::position(), submap::update_lum_add(), and submap::update_lum_rem().

Referenced by update_lum().

◆ update_pathfinding_cache()

void map::update_pathfinding_cache ( int  zlev) const

Definition at line 8782 of file map.cpp.

8783{
8784 auto &cache = get_pathfinding_cache( zlev );
8785 if( !cache.dirty ) {
8786 return;
8787 }
8788
8789 std::uninitialized_fill_n( &cache.special[0][0], MAPSIZE_X * MAPSIZE_Y, PF_NORMAL );
8790
8791 for( int smx = 0; smx < my_MAPSIZE; ++smx ) {
8792 for( int smy = 0; smy < my_MAPSIZE; ++smy ) {
8793 const auto cur_submap = get_submap_at_grid( { smx, smy, zlev } );
8794 if( !cur_submap ) {
8795 return;
8796 }
8797
8798 tripoint p( 0, 0, zlev );
8799
8800 for( int sx = 0; sx < SEEX; ++sx ) {
8801 p.x = sx + smx * SEEX;
8802 for( int sy = 0; sy < SEEY; ++sy ) {
8803 p.y = sy + smy * SEEY;
8804
8805 pf_special cur_value = PF_NORMAL;
8806
8807 maptile tile( cur_submap, point( sx, sy ) );
8808
8809 const auto &terrain = tile.get_ter_t();
8810 const auto &furniture = tile.get_furn_t();
8811 int part;
8812 const vehicle *veh = veh_at_internal( p, part );
8813
8814 const int cost = move_cost_internal( furniture, terrain, veh, part );
8815
8816 if( cost > 2 ) {
8817 cur_value |= PF_SLOW;
8818 } else if( cost <= 0 ) {
8819 cur_value |= PF_WALL;
8820 if( terrain.has_flag( TFLAG_CLIMBABLE ) ) {
8821 cur_value |= PF_CLIMBABLE;
8822 }
8823 }
8824
8825 if( veh != nullptr ) {
8826 cur_value |= PF_VEHICLE;
8827 }
8828
8829 for( const auto &fld : tile.get_field() ) {
8830 const field_entry &cur = fld.second;
8831 const field_type_id type = cur.get_field_type();
8832 const int field_intensity = cur.get_field_intensity();
8833 if( type.obj().get_dangerous( field_intensity - 1 ) ) {
8834 cur_value |= PF_FIELD;
8835 }
8836 }
8837
8838 if( !tile.get_trap_t().is_benign() || !terrain.trap.obj().is_benign() ) {
8839 cur_value |= PF_TRAP;
8840 }
8841
8842 if( terrain.has_flag( TFLAG_GOES_DOWN ) || terrain.has_flag( TFLAG_GOES_UP ) ||
8843 terrain.has_flag( TFLAG_RAMP ) || terrain.has_flag( TFLAG_RAMP_UP ) ||
8844 terrain.has_flag( TFLAG_RAMP_DOWN ) ) {
8845 cur_value |= PF_UPDOWN;
8846 }
8847
8848 if( terrain.has_flag( TFLAG_SHARP ) ) {
8849 cur_value |= PF_SHARP;
8850 }
8851
8852 cache.special[p.x][p.y] = cur_value;
8853 }
8854 }
8855 }
8856 }
8857
8858 cache.dirty = false;
8859}
@ TFLAG_CLIMBABLE
Definition: mapdata.h:307
@ TFLAG_SHARP
Definition: mapdata.h:296
pf_special
Definition: pathfinding.h:7
@ PF_NORMAL
Definition: pathfinding.h:8
@ PF_FIELD
Definition: pathfinding.h:12

References furniture, maptile::get_field(), field_entry::get_field_intensity(), field_entry::get_field_type(), maptile::get_furn_t(), get_pathfinding_cache(), get_submap_at_grid(), maptile::get_ter_t(), maptile::get_trap_t(), trap::is_benign(), MAPSIZE_X, MAPSIZE_Y, move_cost_internal(), my_MAPSIZE, PF_CLIMBABLE, PF_FIELD, PF_NORMAL, PF_SHARP, PF_SLOW, PF_TRAP, PF_UPDOWN, PF_VEHICLE, PF_WALL, SEEX, SEEY, sx, sy, terrain, TFLAG_CLIMBABLE, TFLAG_GOES_DOWN, TFLAG_GOES_UP, TFLAG_RAMP, TFLAG_RAMP_DOWN, TFLAG_RAMP_UP, TFLAG_SHARP, type, veh_at_internal(), tripoint::x, and tripoint::y.

Referenced by get_pathfinding_cache_ref().

◆ update_submap_active_item_status()

void map::update_submap_active_item_status ( const tripoint p)

Definition at line 5587 of file map.cpp.

5588{
5589 point l;
5590 submap *const current_submap = get_submap_at( p, l );
5591 if( current_submap->active_items.empty() ) {
5592 submaps_with_active_items.erase( tripoint( abs_sub.x + p.x / SEEX, abs_sub.y + p.y / SEEY, p.z ) );
5593 }
5594}

References abs_sub, submap::active_items, active_item_cache::empty(), get_submap_at(), SEEX, SEEY, submaps_with_active_items, tripoint::x, tripoint::y, and tripoint::z.

◆ update_suspension_cache()

void map::update_suspension_cache ( const int &  z)

Definition at line 8058 of file map.cpp.

8059{
8060 level_cache &ch = get_cache( z );
8061 if( !ch.suspension_cache_dirty ) {
8062 return;
8063 }
8064 std::list<point> &suspension_cache = ch.suspension_cache;
8066 for( int smx = 0; smx < my_MAPSIZE; ++smx ) {
8067 for( int smy = 0; smy < my_MAPSIZE; ++smy ) {
8068 const submap *cur_submap = get_submap_at_grid( { smx, smy, z } );
8069
8070 if( cur_submap == nullptr ) {
8071 debugmsg( "Tried to run suspension check at (%d,%d,%d) but the submap is not loaded", smx, smy,
8072 z );
8073 continue;
8074 }
8075
8076 for( int sx = 0; sx < SEEX; ++sx ) {
8077 for( int sy = 0; sy < SEEY; ++sy ) {
8078 point sp( sx, sy );
8079 const ter_t &terrain = cur_submap->get_ter( sp ).obj();
8080 if( terrain.has_flag( TFLAG_SUSPENDED ) ) {
8081 tripoint loc( coords::project_combine( point_om_sm( point( smx, smy ) ), point_sm_ms( sp ) ).raw(),
8082 z );
8083 suspension_cache.emplace_back( getabs( loc ).xy() );
8084 }
8085 }
8086 }
8087 }
8088 }
8090 }
8091
8092 for( auto iter = suspension_cache.begin(); iter != suspension_cache.end(); ) {
8093 const point absp = *iter;
8094 const point locp = getlocal( absp );
8095 const tripoint loctp( locp, z );
8096 if( !inbounds( locp ) ) {
8097 ++iter;
8098 continue;
8099 }
8100 const submap *cur_submap = get_submap_at( loctp );
8101 if( cur_submap == nullptr ) {
8102 debugmsg( "Tried to run suspension check at (%d,%d,%d) but the submap is not loaded", locp.x,
8103 locp.y, z );
8104 ++iter;
8105 continue;
8106 }
8107 const ter_t &terrain = ter( locp ).obj();
8108 if( terrain.has_flag( TFLAG_SUSPENDED ) ) {
8109 if( !is_suspension_valid( loctp ) ) {
8110 support_dirty( loctp );
8111 iter = suspension_cache.erase( iter );
8112 } else {
8113 ++iter;
8114 }
8115 } else {
8116 iter = suspension_cache.erase( iter );
8117 }
8118 }
8119 ch.suspension_cache_dirty = false;
8120}
coords::coord_point< point, coords::origin::overmap, coords::sm > point_om_sm
Definition: coordinates.h:477
auto project_combine(const coord_point< PointL, CoarseOrigin, CoarseScale > &coarse, const coord_point< PointR, FineOrigin, FineScale > &fine)
Definition: coordinates.h:413
bool suspension_cache_initialized
Definition: map.h:310

References debugmsg, get_cache(), get_submap_at(), get_submap_at_grid(), submap::get_ter(), getabs(), getlocal(), inbounds(), is_suspension_valid(), my_MAPSIZE, int_id< T >::obj(), coords::project_combine(), SEEX, SEEY, support_dirty(), level_cache::suspension_cache, level_cache::suspension_cache_dirty, level_cache::suspension_cache_initialized, sx, sy, ter(), terrain, TFLAG_SUSPENDED, point::x, and point::y.

Referenced by build_map_cache().

◆ update_vehicle_cache()

void map::update_vehicle_cache ( vehicle ,
int  old_zlevel 
)

◆ update_vehicle_list()

void map::update_vehicle_list ( const submap to,
int  zlev 
)

Definition at line 340 of file map.cpp.

341{
342 // Update vehicle data
343 level_cache &ch = get_cache( zlev );
344 for( const auto &elem : to->vehicles ) {
345 ch.vehicle_list.insert( elem.get() );
346 if( !elem->loot_zones.empty() ) {
347 ch.zone_vehicles.insert( elem.get() );
348 }
349 }
350
352}

References get_cache(), last_full_vehicle_list_dirty, level_cache::vehicle_list, submap::vehicles, and level_cache::zone_vehicles.

Referenced by displace_vehicle(), editmap::mapgen_preview(), rotate(), shift(), and shift_vehicle_z().

◆ update_visibility_cache()

void map::update_visibility_cache ( int  zlev)

Definition at line 5596 of file map.cpp.

5597{
5598 visibility_variables_cache.variables_set = true; // Not used yet
5599 visibility_variables_cache.g_light_level = static_cast<int>( g->light_level( zlev ) );
5600 visibility_variables_cache.vision_threshold = g->u.get_vision_threshold(
5601 get_cache_ref( g->u.posz() ).lm[g->u.posx()][g->u.posy()].max() );
5602
5603 visibility_variables_cache.u_clairvoyance = g->u.clairvoyance();
5604 visibility_variables_cache.u_sight_impaired = g->u.sight_impaired();
5606
5607 int sm_squares_seen[MAPSIZE][MAPSIZE];
5608 std::memset( sm_squares_seen, 0, sizeof( sm_squares_seen ) );
5609
5610 int min_z = fov_3d ? -OVERMAP_DEPTH : zlev;
5611 int max_z = fov_3d ? OVERMAP_HEIGHT : zlev;
5612
5613 for( int z = min_z; z <= max_z; z++ ) {
5614
5615 auto &visibility_cache = get_cache( z ).visibility_cache;
5616
5617 tripoint p;
5618 p.z = z;
5619 int &x = p.x;
5620 int &y = p.y;
5621 for( x = 0; x < MAPSIZE_X; x++ ) {
5622 for( y = 0; y < MAPSIZE_Y; y++ ) {
5624 visibility_cache[x][y] = ll;
5625 if( z == zlev ) {
5626 sm_squares_seen[ x / SEEX ][ y / SEEY ] += ( ll == lit_level::BRIGHT || ll == lit_level::LIT );
5627 }
5628 }
5629 }
5630 }
5631
5632 for( int gridx = 0; gridx < my_MAPSIZE; gridx++ ) {
5633 for( int gridy = 0; gridy < my_MAPSIZE; gridy++ ) {
5634 if( sm_squares_seen[gridx][gridy] > 36 ) { // 25% of the submap is visible
5635 const tripoint sm( gridx, gridy, 0 );
5636 const auto abs_sm = map::abs_sub + sm;
5637 // TODO: fix point types
5638 const tripoint_abs_omt abs_omt( sm_to_omt_copy( abs_sm ) );
5639 overmap_buffer.set_seen( abs_omt, true );
5640 }
5641 }
5642 }
5643}
lit_level apparent_light_at(const tripoint &p, const visibility_variables &cache) const
Determine the visible light level for a tile, based on light_at for the tile, vision distance,...
Definition: lightmap.cpp:700
void set_seen(const tripoint_abs_omt &p, bool seen=true)
static const efftype_id effect_boomered("boomered")
bool variables_set
Definition: map.h:122
bool u_sight_impaired
Definition: map.h:123

References abs_sub, apparent_light_at(), BRIGHT, effect_boomered, fov_3d, g, visibility_variables::g_light_level, get_cache(), get_cache_ref(), LIT, level_cache::lm, MAPSIZE, MAPSIZE_X, MAPSIZE_Y, four_quadrants::max(), my_MAPSIZE, overmap_buffer, OVERMAP_DEPTH, OVERMAP_HEIGHT, SEEX, SEEY, overmapbuffer::set_seen(), coords::sm, sm_to_omt_copy(), visibility_variables::u_clairvoyance, visibility_variables::u_is_boomered, visibility_variables::u_sight_impaired, visibility_variables::variables_set, level_cache::visibility_cache, visibility_variables_cache, visibility_variables::vision_threshold, tripoint::x, tripoint::y, and tripoint::z.

Referenced by game::draw(), draw(), game::get_player_input(), and game::look_around().

◆ use_amount()

std::list< item > map::use_amount ( const tripoint origin,
int  range,
const itype_id type,
int &  quantity,
const std::function< bool(const item &)> &  filter = return_true<item> 
)

Definition at line 4809 of file map.cpp.

4811{
4812 std::list<item> ret;
4813 for( int radius = 0; radius <= range && quantity > 0; radius++ ) {
4814 for( const tripoint &p : points_in_radius( origin, radius ) ) {
4815 if( rl_dist( origin, p ) >= radius ) {
4816 std::list<item> tmp = use_amount_square( p, type, quantity, filter );
4817 ret.splice( ret.end(), tmp );
4818 }
4819 }
4820 }
4821 return ret;
4822}
std::list< item > use_amount_square(const tripoint &p, const itype_id &type, int &quantity, const std::function< bool(const item &)> &filter=return_true< item >)
Definition: map.cpp:4787

References points_in_radius(), cata::hash64_detail::ret, rl_dist(), type, and use_amount_square().

◆ use_amount_square()

std::list< item > map::use_amount_square ( const tripoint p,
const itype_id type,
int &  quantity,
const std::function< bool(const item &)> &  filter = return_true<item> 
)

Definition at line 4787 of file map.cpp.

4789{
4790 std::list<item> ret;
4791 // Handle infinite map sources.
4792 item water = water_from( p );
4793 if( water.typeId() == type ) {
4794 ret.push_back( water );
4795 quantity = 0;
4796 return ret;
4797 }
4798
4799 if( const cata::optional<vpart_reference> vp = veh_at( p ).part_with_feature( "CARGO", true ) ) {
4800 std::list<item> tmp = use_amount_stack( vp->vehicle().get_items( vp->part_index() ), type,
4801 quantity, filter );
4802 ret.splice( ret.end(), tmp );
4803 }
4804 std::list<item> tmp = use_amount_stack( i_at( p ), type, quantity, filter );
4805 ret.splice( ret.end(), tmp );
4806 return ret;
4807}
item water_from(const tripoint &p)
Definition: map.cpp:4375
std::list< item > use_amount_stack(Stack stack, const itype_id &type, int &quantity, const std::function< bool(const item &)> &filter)
Definition: map.cpp:4773

References i_at(), cata::hash64_detail::ret, type, item::typeId(), use_amount_stack(), veh_at(), and water_from().

Referenced by use_amount().

◆ use_charges()

std::list< item > map::use_charges ( const tripoint origin,
int  range,
const itype_id type,
int &  quantity,
const std::function< bool(const item &)> &  filter = return_true<item>,
basecamp bcp = nullptr 
)

Definition at line 4905 of file map.cpp.

4908{
4909 std::list<item> ret;
4910
4911 // populate a grid of spots that can be reached
4912 std::vector<tripoint> reachable_pts;
4913 reachable_flood_steps( reachable_pts, origin, range, 1, 100 );
4914
4915 // We prefer infinite map sources where available, so search for those
4916 // first
4917 for( const tripoint &p : reachable_pts ) {
4918 // Handle infinite map sources.
4919 item water = water_from( p );
4920 if( water.typeId() == type ) {
4921 water.charges = quantity;
4922 ret.push_back( water );
4923 quantity = 0;
4924 return ret;
4925 }
4926 }
4927
4928 if( bcp ) {
4929 ret = bcp->use_charges( type, quantity );
4930 if( quantity <= 0 ) {
4931 return ret;
4932 }
4933 }
4934
4935 for( const tripoint &p : reachable_pts ) {
4936 if( has_furn( p ) ) {
4937 use_charges_from_furn( furn( p ).obj(), type, quantity, this, p, ret, filter );
4938 if( quantity <= 0 ) {
4939 return ret;
4940 }
4941 }
4942
4943 if( accessible_items( p ) ) {
4944 std::list<item> tmp = use_charges_from_stack( i_at( p ), type, quantity, p, filter );
4945 ret.splice( ret.end(), tmp );
4946 if( quantity <= 0 ) {
4947 return ret;
4948 }
4949 }
4950
4951 const optional_vpart_position vp = veh_at( p );
4952 if( !vp ) {
4953 continue;
4954 }
4955
4956 const cata::optional<vpart_reference> kpart = vp.part_with_feature( "FAUCET", true );
4957 const cata::optional<vpart_reference> weldpart = vp.part_with_feature( "WELDRIG", true );
4958 const cata::optional<vpart_reference> craftpart = vp.part_with_feature( "CRAFTRIG", true );
4959 const cata::optional<vpart_reference> forgepart = vp.part_with_feature( "FORGE", true );
4960 const cata::optional<vpart_reference> kilnpart = vp.part_with_feature( "KILN", true );
4961 const cata::optional<vpart_reference> chempart = vp.part_with_feature( "CHEMLAB", true );
4962 const cata::optional<vpart_reference> autoclavepart = vp.part_with_feature( "AUTOCLAVE", true );
4963 const cata::optional<vpart_reference> cargo = vp.part_with_feature( "CARGO", true );
4964
4965 if( kpart ) { // we have a faucet, now to see what to drain
4966 itype_id ftype = itype_id::NULL_ID();
4967
4968 // Special case hotplates which draw battery power
4969 if( type == itype_hotplate ) {
4970 ftype = itype_battery;
4971 } else {
4972 ftype = type;
4973 }
4974
4975 // TODO: add a sane birthday arg
4977 tmp.charges = kpart->vehicle().drain( ftype, quantity );
4978 // TODO: Handle water poison when crafting starts respecting it
4979 quantity -= tmp.charges;
4980 ret.push_back( tmp );
4981
4982 if( quantity == 0 ) {
4983 return ret;
4984 }
4985 }
4986
4987 if( weldpart ) { // we have a weldrig, now to see what to drain
4988 itype_id ftype = itype_id::NULL_ID();
4989
4990 if( type == itype_welder ) {
4991 ftype = itype_battery;
4992 } else if( type == itype_soldering_iron ) {
4993 ftype = itype_battery;
4994 }
4995 // TODO: add a sane birthday arg
4997 tmp.charges = weldpart->vehicle().drain( ftype, quantity );
4998 quantity -= tmp.charges;
4999 ret.push_back( tmp );
5000
5001 if( quantity == 0 ) {
5002 return ret;
5003 }
5004 }
5005
5006 if( craftpart ) { // we have a craftrig, now to see what to drain
5007 itype_id ftype = itype_id::NULL_ID();
5008
5009 if( type == itype_press ) {
5010 ftype = itype_battery;
5011 } else if( type == itype_vac_sealer ) {
5012 ftype = itype_battery;
5013 } else if( type == itype_dehydrator ) {
5014 ftype = itype_battery;
5015 } else if( type == itype_food_processor ) {
5016 ftype = itype_battery;
5017 }
5018
5019 // TODO: add a sane birthday arg
5021 tmp.charges = craftpart->vehicle().drain( ftype, quantity );
5022 quantity -= tmp.charges;
5023 ret.push_back( tmp );
5024
5025 if( quantity == 0 ) {
5026 return ret;
5027 }
5028 }
5029
5030 if( forgepart ) { // we have a veh_forge, now to see what to drain
5031 itype_id ftype = itype_id::NULL_ID();
5032
5033 if( type == itype_forge ) {
5034 ftype = itype_battery;
5035 }
5036
5037 // TODO: add a sane birthday arg
5039 tmp.charges = forgepart->vehicle().drain( ftype, quantity );
5040 quantity -= tmp.charges;
5041 ret.push_back( tmp );
5042
5043 if( quantity == 0 ) {
5044 return ret;
5045 }
5046 }
5047
5048 if( kilnpart ) { // we have a veh_kiln, now to see what to drain
5049 itype_id ftype = itype_id::NULL_ID();
5050
5051 if( type == itype_kiln ) {
5052 ftype = itype_battery;
5053 }
5054
5055 // TODO: add a sane birthday arg
5057 tmp.charges = kilnpart->vehicle().drain( ftype, quantity );
5058 quantity -= tmp.charges;
5059 ret.push_back( tmp );
5060
5061 if( quantity == 0 ) {
5062 return ret;
5063 }
5064 }
5065
5066 if( chempart ) { // we have a chem_lab, now to see what to drain
5067 itype_id ftype = itype_id::NULL_ID();
5068
5069 if( type == itype_chemistry_set ) {
5070 ftype = itype_battery;
5071 } else if( type == itype_hotplate ) {
5072 ftype = itype_battery;
5073 } else if( type == itype_electrolysis_kit ) {
5074 ftype = itype_battery;
5075 }
5076
5077 // TODO: add a sane birthday arg
5079 tmp.charges = chempart->vehicle().drain( ftype, quantity );
5080 quantity -= tmp.charges;
5081 ret.push_back( tmp );
5082
5083 if( quantity == 0 ) {
5084 return ret;
5085 }
5086 }
5087
5088 if( autoclavepart ) { // we have an autoclave, now to see what to drain
5089 itype_id ftype = itype_id::NULL_ID();
5090
5091 if( type == itype_autoclave ) {
5092 ftype = itype_battery;
5093 }
5094
5095 // TODO: add a sane birthday arg
5097 tmp.charges = autoclavepart->vehicle().drain( ftype, quantity );
5098 quantity -= tmp.charges;
5099 ret.push_back( tmp );
5100
5101 if( quantity == 0 ) {
5102 return ret;
5103 }
5104 }
5105
5106 if( cargo ) {
5107 std::list<item> tmp =
5108 use_charges_from_stack( cargo->vehicle().get_items( cargo->part_index() ), type, quantity, p,
5109 filter );
5110 ret.splice( ret.end(), tmp );
5111 if( quantity <= 0 ) {
5112 return ret;
5113 }
5114 }
5115 }
5116
5117 return ret;
5118}
std::list< item > use_charges(const itype_id &fake_id, int &quantity)
Definition: basecamp.cpp:584
bool accessible_items(const tripoint &t) const
Check whether the player can access the items located .
Definition: map.cpp:6555
void reachable_flood_steps(std::vector< tripoint > &reachable_pts, const tripoint &f, int range, int cost_min, int cost_max) const
Populates a vector of points that are reachable within a number of steps from a point.
Definition: map.cpp:6284
static const itype_id itype_autoclave("autoclave")
static void use_charges_from_furn(const furn_t &f, const itype_id &type, int &quantity, map *m, const tripoint &p, std::list< item > &ret, const std::function< bool(const item &)> &filter)
Definition: map.cpp:4839
static const itype_id itype_soldering_iron("soldering_iron")
static const itype_id itype_chemistry_set("chemistry_set")
std::list< item > use_charges_from_stack(Stack stack, const itype_id &type, int &quantity, const tripoint &pos, const std::function< bool(const item &)> &filter)
Definition: map.cpp:4825
static const itype_id itype_press("press")
static const itype_id itype_hotplate("hotplate")
static const itype_id itype_electrolysis_kit("electrolysis_kit")
static const itype_id itype_food_processor("food_processor")
static const itype_id itype_forge("forge")
static const itype_id itype_battery("battery")
static const itype_id itype_dehydrator("dehydrator")
static const itype_id itype_kiln("kiln")
static const itype_id itype_welder("welder")
static const itype_id itype_vac_sealer("vac_sealer")

References accessible_items(), item::charges, furn(), has_furn(), i_at(), itype_autoclave, itype_battery, itype_chemistry_set, itype_dehydrator, itype_electrolysis_kit, itype_food_processor, itype_forge, itype_hotplate, itype_kiln, itype_press, itype_soldering_iron, itype_vac_sealer, itype_welder, string_id< itype >::NULL_ID(), optional_vpart_position::part_with_feature(), reachable_flood_steps(), cata::hash64_detail::ret, calendar::start_of_cataclysm, type, item::typeId(), basecamp::use_charges(), use_charges_from_furn(), use_charges_from_stack(), veh_at(), and water_from().

Referenced by basecamp_action_components::consume_components(), player::consume_items(), player::consume_tools(), and iexamine::use_furn_fake_item().

◆ valid_move()

bool map::valid_move ( const tripoint from,
const tripoint to,
bool  bash = false,
bool  flying = false,
bool  via_ramp = false 
) const

Returns true if a creature could walk from from to to in one step.

That is, if the tiles are adjacent and either on the same z-level or connected by stairs or (in case of flying monsters) open air with no floors.

Definition at line 1861 of file map.cpp.

1863{
1864 // Used to account for the fact that older versions of GCC can trip on the if statement here.
1865 assert( to.z > std::numeric_limits<int>::min() );
1866 // Note: no need to check inbounds here, because maptile_at will do that
1867 // If oob tile is supplied, the maptile_at will be an unpassable "null" tile
1868 if( std::abs( from.x - to.x ) > 1 || std::abs( from.y - to.y ) > 1 ||
1869 std::abs( from.z - to.z ) > 1 ) {
1870 return false;
1871 }
1872
1873 if( from.z == to.z ) {
1874 // But here we need to, to prevent bashing critters
1875 return passable( to ) || ( bash && inbounds( to ) );
1876 } else if( !zlevels ) {
1877 return false;
1878 }
1879
1880 const bool going_up = from.z < to.z;
1881
1882 const tripoint &up_p = going_up ? to : from;
1883 const tripoint &down_p = going_up ? from : to;
1884
1885 const maptile up = maptile_at( up_p );
1886 const ter_t &up_ter = up.get_ter_t();
1887 if( up_ter.id.is_null() ) {
1888 return false;
1889 }
1890 // Checking for ledge is a workaround for the case when mapgen doesn't
1891 // actually make a valid ledge drop location with zlevels on, this forces
1892 // at least one zlevel drop and if down_ter is impassible it's probably
1893 // inside a wall, we could workaround that further but it's unnecessary.
1894 const bool up_is_ledge = tr_at( up_p ).loadid == tr_ledge;
1895
1896 if( up_ter.movecost == 0 ) {
1897 // Unpassable tile
1898 return false;
1899 }
1900
1901 const maptile down = maptile_at( down_p );
1902 const ter_t &down_ter = down.get_ter_t();
1903 if( down_ter.id.is_null() ) {
1904 return false;
1905 }
1906
1907 if( !up_is_ledge && down_ter.movecost == 0 ) {
1908 // Unpassable tile
1909 return false;
1910 }
1911
1912 if( !up_ter.has_flag( TFLAG_NO_FLOOR ) && !up_ter.has_flag( TFLAG_GOES_DOWN ) && !up_is_ledge &&
1913 !via_ramp ) {
1914 // Can't move from up to down
1915 if( std::abs( from.x - to.x ) == 1 || std::abs( from.y - to.y ) == 1 ) {
1916 // Break the move into two - vertical then horizontal
1917 tripoint midpoint( down_p.xy(), up_p.z );
1918 return valid_move( down_p, midpoint, bash, flying, via_ramp ) &&
1919 valid_move( midpoint, up_p, bash, flying, via_ramp );
1920 }
1921 return false;
1922 }
1923
1924 if( !flying && !down_ter.has_flag( TFLAG_GOES_UP ) && !down_ter.has_flag( TFLAG_RAMP ) &&
1925 !up_is_ledge && !via_ramp ) {
1926 // Can't safely reach the lower tile
1927 return false;
1928 }
1929
1930 if( bash ) {
1931 return true;
1932 }
1933
1934 int part_up;
1935 const vehicle *veh_up = veh_at_internal( up_p, part_up );
1936 if( veh_up != nullptr ) {
1937 // TODO: Hatches below the vehicle, passable frames
1938 return false;
1939 }
1940
1941 int part_down;
1942 const vehicle *veh_down = veh_at_internal( down_p, part_down );
1943 if( veh_down != nullptr && veh_down->roof_at_part( part_down ) >= 0 ) {
1944 // TODO: OPEN (and only open) hatches from above
1945 return false;
1946 }
1947
1948 // Currently only furniture can block movement if everything else is OK
1949 // TODO: Vehicles with boards in the given spot
1950 return up.get_furn_t().movecost >= 0;
1951}
coords::coord_point< Point, Origin, Scale > midpoint(const coords::coord_point< Point, Origin, Scale > &loc1, const coords::coord_point< Point, Origin, Scale > &loc2)
Definition: coordinates.h:562
trap_id loadid
Definition: trap.h:88

References bash(), map_data_common_t::has_flag(), ter_t::id, inbounds(), string_id< T >::is_null(), trap::loadid, maptile_at(), midpoint(), map_data_common_t::movecost, passable(), vehicle::roof_at_part(), TFLAG_GOES_DOWN, TFLAG_GOES_UP, TFLAG_NO_FLOOR, TFLAG_RAMP, tr_at(), tr_ledge, valid_move(), veh_at_internal(), tripoint::x, tripoint::xy(), tripoint::y, tripoint::z, and zlevels.

Referenced by map_funcs::climbing_cost(), combined_movecost(), explosion_handler::do_blast(), draw_critter_internal(), has_floor_or_support(), scent_map::inbounds(), iexamine::ledge(), monster::move(), process_fields_in_submap(), route(), spread_gas(), monster::stumble(), and valid_move().

◆ veh_at()

optional_vpart_position map::veh_at ( const tripoint p) const

Checks if tile is occupied by vehicle and by which part.

Parameters
pTile to check for vehicle

Definition at line 1009 of file map.cpp.

1010{
1011 if( !inbounds( p ) || !const_cast<map *>( this )->get_cache( p.z ).veh_in_active_range ) {
1013 }
1014
1015 int part_num = 1;
1016 vehicle *const veh = const_cast<map *>( this )->veh_at_internal( p, part_num );
1017 if( !veh ) {
1019 }
1020 return optional_vpart_position( vpart_position( *veh, part_num ) );
1021
1022}
static constexpr nullopt_t nullopt
Definition: optional.h:22

References get_cache(), inbounds(), cata::nullopt, veh_at_internal(), level_cache::veh_in_active_range, and tripoint::z.

Referenced by Character::activate_bionic(), activity_on_turn_move_loot(), zone_manager::add(), add_splatter(), add_vehicle_to_map(), apply_faction_ownership(), are_requirements_nearby(), Creature::auto_find_hostile_target(), Character::base_comfort_value(), bash(), bash_rating(), bash_vehicle(), board_vehicle(), build_seen_cache(), VehicleSpawnFunction::builtin_parkinglot(), Character::burn_fuel(), can_do_activity_there(), can_examine_at(), can_interact_at(), can_pickup_at(), can_put_items(), can_use_bipod(), check_art_charge_req(), vehicle::autodrive_controller::check_drivable(), player::check_eligible_containers_for_crafting(), construct::check_empty(), vehicle::check_heli_ascend(), vehicle::check_heli_descend(), climb_difficulty(), doors::close_door(), veh_interact::complete_vehicle(), game::control_vehicle(), coverage(), creature_in_field(), crush(), cycle_action(), debug_menu::debug(), deregister_vehicle_zone(), activity_handlers::repair_activity_hack::anonymous_namespace{activity_handlers.cpp}::discharge_real_power_source(), explosion_handler::do_blast(), game::do_turn(), editmap_hilight::draw(), editmap::draw_main_ui_overlay(), drop_vehicle(), game::examine(), npc::execute_action(), ranged::expected_coverage(), fetch_activity(), activity_handlers::fill_liquid_do_turn(), find_auto_consume(), npc::find_item(), Character::find_remote_fuel(), fire(), game::fling_creature(), Character::floor_bedding_warmth(), Character::floor_item_warmth(), game::forced_door_closing(), inventory::form_from_map(), generic_multi_activity_check_requirement(), avatar::get_book_reader(), game::get_dangerous_tile(), player::get_eligible_containers_for_crafting(), activity_handlers::repair_activity_hack::anonymous_namespace{activity_handlers.cpp}::get_fake_tool(), liquid_handler::get_liquid_target(), overmap_ui::get_overmap_path_to(), game::get_veh_dir_indicator_location(), grab(), game::grabbed_furn_move(), game::grabbed_veh_move(), ranged::gunmode_checks_common(), ranged::gunmode_checks_weapon(), handbrake(), game::handle_action(), handle_action_menu(), Character::has_alarm_clock(), has_nearby_chair(), has_nearby_table(), jmapgen_setmap::has_vehicle_collision(), mapgen_function_json_base::has_vehicle_collision(), jmapgen_alternativly< PieceType >::has_vehicle_collision(), jmapgen_sign::has_vehicle_collision(), jmapgen_vending_machine::has_vehicle_collision(), jmapgen_toilet::has_vehicle_collision(), jmapgen_gaspump::has_vehicle_collision(), jmapgen_vehicle::has_vehicle_collision(), jmapgen_trap::has_vehicle_collision(), jmapgen_furniture::has_vehicle_collision(), jmapgen_terrain::has_vehicle_collision(), jmapgen_computer::has_vehicle_collision(), jmapgen_sealed_item::has_vehicle_collision(), Character::has_watch(), haul(), Character::in_climate_control(), advanced_inv_area::init(), is_bashable(), weather::is_sheltered(), Character::is_snuggling(), game::load(), make_active(), mine_activity(), monster_in_field(), mop_spills(), avatar_action::move(), move_cost(), npc::move_to(), move_vehicle(), game::moving_vehicle_dismount(), MapExtras::mx_helicopter(), obstacle_coverage(), obstacle_name(), open(), open_door(), vehicle::part_collision(), Character::passive_power_gen(), liquid_handler::perform_liquid_transfer(), game::phasing_move(), npc::pick_up_item(), game::place_player(), player_in_field(), pldrive(), game::print_all_tile_info(), projectile_attack(), vehicle_part::properties_to_item(), put_into_vehicle_or_drop(), game::remoteveh(), DefaultRemovePartHandler::removed(), zone_manager::revert_vzones(), iexamine::rubble(), conditional_t< T >::set_is_driving(), set_item_map_or_vehicle(), shoot(), explosion_handler::shrapnel(), iexamine::shrub_wildveggies(), spell_effect::spawn_summoned_vehicle(), autodrive_activity_actor::start(), activity_handlers::start_engines_finish(), supports_above(), game::swap_critters(), avatar_action::swim(), tidy_activity(), unboard_vehicle(), Character::update_bodytemp(), editmap::update_view_with_help(), deploy_furn_actor::use(), deploy_tent_actor::use(), use_amount_square(), use_charges(), game::validate_linked_vehicles(), vehicle_activity(), activity_handlers::vehicle_finish(), vehicle_selector::vehicle_selector(), wait(), game::walk_move(), avatar_action::wield(), and workbench_crafting_speed_multiplier().

◆ veh_at_internal() [1/2]

vehicle * map::veh_at_internal ( const tripoint p,
int &  part_num 
)

Definition at line 1044 of file map.cpp.

1045{
1046 return const_cast<vehicle *>( const_cast<const map *>( this )->veh_at_internal( p, part_num ) );
1047}

References veh_at_internal().

Referenced by draw_from_above(), draw_maptile(), process_fields_in_submap(), route(), update_pathfinding_cache(), valid_move(), veh_at(), and veh_at_internal().

◆ veh_at_internal() [2/2]

const vehicle * map::veh_at_internal ( const tripoint p,
int &  part_num 
) const

Definition at line 1024 of file map.cpp.

1025{
1026 // This function is called A LOT. Move as much out of here as possible.
1027 const level_cache &ch = get_cache( p.z );
1028 if( !ch.veh_in_active_range || !ch.veh_exists_at[p.x][p.y] ) {
1029 part_num = -1;
1030 return nullptr; // Clear cache indicates no vehicle. This should optimize a great deal.
1031 }
1032
1033 const auto it = ch.veh_cached_parts.find( p );
1034 if( it != ch.veh_cached_parts.end() ) {
1035 part_num = it->second.second;
1036 return it->second.first;
1037 }
1038
1039 debugmsg( "vehicle part cache indicated vehicle not found: %d %d %d", p.x, p.y, p.z );
1040 part_num = -1;
1041 return nullptr;
1042}

References debugmsg, get_cache(), level_cache::veh_cached_parts, level_cache::veh_exists_at, level_cache::veh_in_active_range, tripoint::x, tripoint::y, and tripoint::z.

◆ vehicle_vehicle_collision()

float map::vehicle_vehicle_collision ( vehicle veh,
vehicle veh2,
const std::vector< veh_collision > &  collisions 
)

Definition at line 762 of file map.cpp.

764{
765 if( &veh == &veh2 ) {
766 debugmsg( "Vehicle %s collided with itself", veh.name );
767 return 0.0f;
768 }
769
770 // Effects of colliding with another vehicle:
771 // transfers of momentum, skidding,
772 // parts are damaged/broken on both sides,
773 // remaining times are normalized
774 const veh_collision &c = collisions[0];
775 add_msg( m_bad, _( "The %1$s's %2$s collides with %3$s's %4$s." ),
776 veh.name, veh.part_info( c.part ).name(),
777 veh2.name, veh2.part_info( c.target_part ).name() );
778
779 const bool vertical = veh.sm_pos.z != veh2.sm_pos.z;
780
781 // Used to calculate the epicenter of the collision.
782 point epicenter1;
783 point epicenter2;
784
785 float dmg;
786 // Vertical collisions will be simpler for a while (1D)
787 if( !vertical ) {
788 // For reference, a cargo truck weighs ~25300, a bicycle 690,
789 // and 38mph is 3800 'velocity'
790 rl_vec2d velo_veh1 = veh.velo_vec();
791 rl_vec2d velo_veh2 = veh2.velo_vec();
792 const float m1 = to_kilogram( veh.total_mass() );
793 const float m2 = to_kilogram( veh2.total_mass() );
794 //Energy of vehicle1 and vehicle2 before collision
795 float E = 0.5 * m1 * velo_veh1.magnitude() * velo_veh1.magnitude() +
796 0.5 * m2 * velo_veh2.magnitude() * velo_veh2.magnitude();
797
798 // Collision_axis
799 point cof1 = veh .rotated_center_of_mass();
800 point cof2 = veh2.rotated_center_of_mass();
801 int &x_cof1 = cof1.x;
802 int &y_cof1 = cof1.y;
803 int &x_cof2 = cof2.x;
804 int &y_cof2 = cof2.y;
805 rl_vec2d collision_axis_y;
806
807 collision_axis_y.x = ( veh.global_pos3().x + x_cof1 ) - ( veh2.global_pos3().x + x_cof2 );
808 collision_axis_y.y = ( veh.global_pos3().y + y_cof1 ) - ( veh2.global_pos3().y + y_cof2 );
809 collision_axis_y = collision_axis_y.normalized();
810 rl_vec2d collision_axis_x = collision_axis_y.rotated( M_PI / 2 );
811 // imp? & delta? & final? reworked:
812 // newvel1 =( vel1 * ( mass1 - mass2 ) + ( 2 * mass2 * vel2 ) ) / ( mass1 + mass2 )
813 // as per http://en.wikipedia.org/wiki/Elastic_collision
814 //velocity of veh1 before collision in the direction of collision_axis_y
815 float vel1_y = collision_axis_y.dot_product( velo_veh1 );
816 float vel1_x = collision_axis_x.dot_product( velo_veh1 );
817 //velocity of veh2 before collision in the direction of collision_axis_y
818 float vel2_y = collision_axis_y.dot_product( velo_veh2 );
819 float vel2_x = collision_axis_x.dot_product( velo_veh2 );
820 // e = 0 -> inelastic collision
821 // e = 1 -> elastic collision
822 float e = get_collision_factor( vel1_y / 100 - vel2_y / 100 );
823
824 // Velocity after collision
825 // vel1_x_a = vel1_x, because in x-direction we have no transmission of force
826 float vel1_x_a = vel1_x;
827 float vel2_x_a = vel2_x;
828 // Transmission of force only in direction of collision_axix_y
829 // Equation: partially elastic collision
830 float vel1_y_a = ( m2 * vel2_y * ( 1 + e ) + vel1_y * ( m1 - m2 * e ) ) / ( m1 + m2 );
831 float vel2_y_a = ( m1 * vel1_y * ( 1 + e ) + vel2_y * ( m2 - m1 * e ) ) / ( m1 + m2 );
832 // Add both components; Note: collision_axis is normalized
833 rl_vec2d final1 = collision_axis_y * vel1_y_a + collision_axis_x * vel1_x_a;
834 rl_vec2d final2 = collision_axis_y * vel2_y_a + collision_axis_x * vel2_x_a;
835
836 veh.move.init( final1.as_point() );
837 if( final1.dot_product( veh.face_vec() ) < 0 ) {
838 // Car is being pushed backwards. Make it move backwards
839 veh.velocity = -final1.magnitude();
840 } else {
841 veh.velocity = final1.magnitude();
842 }
843
844 veh2.move.init( final2.as_point() );
845 if( final2.dot_product( veh2.face_vec() ) < 0 ) {
846 // Car is being pushed backwards. Make it move backwards
847 veh2.velocity = -final2.magnitude();
848 } else {
849 veh2.velocity = final2.magnitude();
850 }
851
852 //give veh2 the initiative to proceed next before veh1
853 float avg_of_turn = ( veh2.of_turn + veh.of_turn ) / 2;
854 if( avg_of_turn < .1f ) {
855 avg_of_turn = .1f;
856 }
857
858 veh.of_turn = avg_of_turn * .9;
859 veh2.of_turn = avg_of_turn * 1.1;
860
861 //Energy after collision
862 float E_a = 0.5 * m1 * final1.magnitude() * final1.magnitude() +
863 0.5 * m2 * final2.magnitude() * final2.magnitude();
864 float d_E = E - E_a; //Lost energy at collision -> deformation energy
865 dmg = std::abs( d_E / 1000 / 2000 ); //adjust to balance damage
866 } else {
867 const float m1 = to_kilogram( veh.total_mass() );
868 // Collision is perfectly inelastic for simplicity
869 // Assume veh2 is standing still
870 dmg = std::abs( veh.vertical_velocity / 100 ) * m1 / 10;
871 veh.vertical_velocity = 0;
872 }
873
874 float dmg_veh1 = dmg * 0.5;
875 float dmg_veh2 = dmg * 0.5;
876
877 int coll_parts_cnt = 0; //quantity of colliding parts between veh1 and veh2
878 for( const auto &veh_veh_coll : collisions ) {
879 if( &veh2 == static_cast<vehicle *>( veh_veh_coll.target ) ) {
880 coll_parts_cnt++;
881 }
882 }
883
884 const float dmg1_part = dmg_veh1 / coll_parts_cnt;
885 const float dmg2_part = dmg_veh2 / coll_parts_cnt;
886
887 //damage colliding parts (only veh1 and veh2 parts)
888 for( const auto &veh_veh_coll : collisions ) {
889 if( &veh2 != static_cast<vehicle *>( veh_veh_coll.target ) ) {
890 continue;
891 }
892
893 int parm1 = veh.part_with_feature( veh_veh_coll.part, VPFLAG_ARMOR, true );
894 if( parm1 < 0 ) {
895 parm1 = veh_veh_coll.part;
896 }
897 int parm2 = veh2.part_with_feature( veh_veh_coll.target_part, VPFLAG_ARMOR, true );
898 if( parm2 < 0 ) {
899 parm2 = veh_veh_coll.target_part;
900 }
901
902 epicenter1 += veh.part( parm1 ).mount;
903 veh.damage( parm1, dmg1_part, DT_BASH );
904
905 epicenter2 += veh2.part( parm2 ).mount;
906 veh2.damage( parm2, dmg2_part, DT_BASH );
907 }
908
909 epicenter2.x /= coll_parts_cnt;
910 epicenter2.y /= coll_parts_cnt;
911
912 if( dmg2_part > 100 ) {
913 // Shake vehicle because of collision
914 veh2.damage_all( dmg2_part / 2, dmg2_part, DT_BASH, epicenter2 );
915 }
916
917 if( dmg_veh1 > 800 ) {
918 veh.skidding = true;
919 }
920
921 if( dmg_veh2 > 800 ) {
922 veh2.skidding = true;
923 }
924
925 // Return the impulse of the collision
926 return dmg_veh1;
927}
rl_vec2d face_vec() const
const point & rotated_center_of_mass() const
Definition: vehicle.cpp:3327
rl_vec2d velo_vec() const
float of_turn
Definition: vehicle.h:1931
std::string name() const
Translated name of a part.
Definition: veh_type.cpp:699
#define M_PI
Definition: math_defines.h:21
point as_point() const
Definition: line.cpp:686
rl_vec2d rotated(float angle) const
Definition: line.cpp:647
float magnitude() const
Definition: line.cpp:610
rl_vec2d normalized() const
Definition: line.cpp:620
float y
Definition: point_float.h:13
float x
Definition: point_float.h:12
float dot_product(const rl_vec2d &v) const
Definition: line.cpp:664
@ VPFLAG_ARMOR
Definition: veh_type.h:32
float get_collision_factor(float delta_v)

References _, add_msg(), rl_vec2d::as_point(), c, vehicle::damage(), vehicle::damage_all(), debugmsg, rl_vec2d::dot_product(), DT_BASH, vehicle::face_vec(), get_collision_factor(), vehicle::global_pos3(), tileray::init(), m_bad, M_PI, rl_vec2d::magnitude(), vehicle_part::mount, vehicle::move, vpart_info::name(), vehicle::name, rl_vec2d::normalized(), vehicle::of_turn, vehicle::part(), vehicle::part_info(), vehicle::part_with_feature(), rl_vec2d::rotated(), vehicle::rotated_center_of_mass(), vehicle::skidding, vehicle::sm_pos, units::to_kilogram(), vehicle::total_mass(), vehicle::velo_vec(), vehicle::velocity, vehicle::vertical_velocity, VPFLAG_ARMOR, point::x, tripoint::x, rl_vec2d::x, point::y, tripoint::y, rl_vec2d::y, and tripoint::z.

Referenced by move_vehicle().

◆ vehicle_wheel_traction()

float map::vehicle_wheel_traction ( const vehicle veh,
bool  ignore_movement_modifiers = false 
) const

Definition at line 1567 of file vehicle_move.cpp.

1569{
1570 if( veh.is_in_water( true ) ) {
1571 return veh.can_float() ? 1.0f : -1.0f;
1572 }
1573 if( veh.is_in_water() && veh.is_watercraft() && veh.can_float() ) {
1574 return 1.0f;
1575 }
1576
1577 const auto &wheel_indices = veh.wheelcache;
1578 int num_wheels = wheel_indices.size();
1579 if( num_wheels == 0 ) {
1580 // TODO: Assume it is digging in dirt
1581 // TODO: Return something that could be reused for dragging
1582 return 0.0f;
1583 }
1584
1585 float traction_wheel_area = 0.0f;
1586
1587 if( vehicle_movement::is_on_rails( *this, veh ) ) {
1588 // Vehicles on rails are considered to have all of their wheels on rails
1589 for( int p : veh.rail_wheelcache ) {
1590 traction_wheel_area += veh.cpart( p ).wheel_area();
1591 }
1592 return traction_wheel_area;
1593 }
1594
1595 for( int p : wheel_indices ) {
1596 const tripoint &pp = veh.global_part_pos3( p );
1597 const int wheel_area = veh.cpart( p ).wheel_area();
1598
1599 const auto &tr = ter( pp ).obj();
1600 // Deep water and air
1601 if( tr.has_flag( TFLAG_DEEP_WATER ) || tr.has_flag( TFLAG_NO_FLOOR ) ) {
1602 // No traction from wheel in water or air
1603 continue;
1604 }
1605
1606 int move_mod = move_cost_ter_furn( pp );
1607 if( move_mod == 0 ) {
1608 // Vehicle locked in wall
1609 // Shouldn't happen, but does
1610 return 0.0f;
1611 }
1612
1613 for( const auto &terrain_mod : veh.part_info( p ).wheel_terrain_mod() ) {
1614 if( !tr.has_flag( terrain_mod.first ) ) {
1615 move_mod += terrain_mod.second;
1616 break;
1617 }
1618 }
1619
1620 // Ignore the movement modifier if needed.
1621 if( ignore_movement_modifiers ) {
1622 move_mod = 2;
1623 }
1624
1625 traction_wheel_area += 2.0 * wheel_area / move_mod;
1626 }
1627
1628 return traction_wheel_area;
1629}
bool is_watercraft() const
Definition: vehicle.cpp:4217
std::vector< int > rail_wheelcache
Definition: vehicle.h:1820
bool can_float() const
can_float does the vehicle have freeboard or does it overflow with water?
Definition: vehicle.cpp:4154
std::vector< std::pair< std::string, int > > wheel_terrain_mod() const
Definition: veh_type.cpp:897
bool is_on_rails(const map &m, const vehicle &veh)
Returns whether the vehicle is currently on rails.

References vehicle::can_float(), vehicle::cpart(), vehicle::global_part_pos3(), vehicle::is_in_water(), vehicle_movement::is_on_rails(), vehicle::is_watercraft(), move_cost_ter_furn(), int_id< T >::obj(), vehicle::part_info(), vehicle::rail_wheelcache, ter(), TFLAG_DEEP_WATER, TFLAG_NO_FLOOR, vehicle_part::wheel_area(), vpart_info::wheel_terrain_mod(), and vehicle::wheelcache.

Referenced by vehicle::act_on_map(), and move_vehicle().

◆ vehmove()

void map::vehmove ( )

Definition at line 414 of file map.cpp.

415{
416 // give vehicles movement points
417 VehicleList vehicle_list;
418 int minz = zlevels ? -OVERMAP_DEPTH : abs_sub.z;
419 int maxz = zlevels ? OVERMAP_HEIGHT : abs_sub.z;
420 for( int zlev = minz; zlev <= maxz; ++zlev ) {
421 level_cache &cache = get_cache( zlev );
422 for( vehicle *veh : cache.vehicle_list ) {
423 veh->gain_moves();
424 veh->slow_leak();
426 w.v = veh;
427 vehicle_list.push_back( w );
428 }
429 }
430
431 // 15 equals 3 >50mph vehicles, or up to 15 slow (1 square move) ones
432 // But 15 is too low for V12 death-bikes, let's put 100 here
433 for( int count = 0; count < 100; count++ ) {
434 if( !vehproceed( vehicle_list ) ) {
435 break;
436 }
437 }
438 // Process item removal on the vehicles that were modified this turn.
439 // Use a copy because part_removal_cleanup can modify the container.
440 auto temp = dirty_vehicle_list;
441 for( const auto &elem : temp ) {
442 auto same_ptr = [ elem ]( const struct wrapped_vehicle & tgt ) {
443 return elem == tgt.v;
444 };
445 if( std::find_if( vehicle_list.begin(), vehicle_list.end(), same_ptr ) !=
446 vehicle_list.end() ) {
447 elem->part_removal_cleanup();
448 }
449 }
450 dirty_vehicle_list.clear();
451 // The bool tracks whether the vehicles is on the map or not.
452 std::map<vehicle *, bool> connected_vehicles;
453 for( int zlev = minz; zlev <= maxz; ++zlev ) {
454 level_cache &cache = get_cache( zlev );
455 vehicle::enumerate_vehicles( connected_vehicles, cache.vehicle_list );
456 }
457 for( std::pair<vehicle *const, bool> &veh_pair : connected_vehicles ) {
458 veh_pair.first->idle( veh_pair.second );
459 }
460}
bool vehproceed(VehicleList &vehicle_list)
Definition: map.cpp:462
static void enumerate_vehicles(std::map< vehicle *, bool > &connected_vehicles, const std::set< vehicle * > &vehicle_list)
Use grid traversal to enumerate all connected vehicles.
Definition: vehicle.cpp:4927
void slow_leak()
Definition: vehicle.cpp:5294
void gain_moves()
Definition: vehicle.cpp:5541

References abs_sub, detail::count(), dirty_vehicle_list, vehicle::enumerate_vehicles(), vehicle::gain_moves(), get_cache(), OVERMAP_DEPTH, OVERMAP_HEIGHT, vehicle::slow_leak(), wrapped_vehicle::v, level_cache::vehicle_list, vehproceed(), tripoint::z, and zlevels.

Referenced by game::do_turn().

◆ vehproceed()

bool map::vehproceed ( VehicleList vehicle_list)

Definition at line 462 of file map.cpp.

463{
464 wrapped_vehicle *cur_veh = nullptr;
465 float max_of_turn = 0;
466 // First horizontal movement
467 for( wrapped_vehicle &vehs_v : vehicle_list ) {
468 if( vehs_v.v->of_turn > max_of_turn ) {
469 cur_veh = &vehs_v;
470 max_of_turn = cur_veh->v->of_turn;
471 }
472 }
473
474 // Then vertical-only movement
475 if( cur_veh == nullptr ) {
476 for( wrapped_vehicle &vehs_v : vehicle_list ) {
477 if( vehs_v.v->is_falling || ( vehs_v.v->is_rotorcraft() && vehs_v.v->get_z_change() != 0 ) ) {
478 cur_veh = &vehs_v;
479 break;
480 }
481 }
482 }
483
484 if( cur_veh == nullptr ) {
485 return false;
486 }
487
488 cur_veh->v = cur_veh->v->act_on_map();
489 if( cur_veh->v == nullptr ) {
490 vehicle_list = get_vehicles();
491 }
492
493 // confirm that veh_in_active_range is still correct for each z-level
494 int minz = zlevels ? -OVERMAP_DEPTH : abs_sub.z;
495 int maxz = zlevels ? OVERMAP_HEIGHT : abs_sub.z;
496 for( int zlev = minz; zlev <= maxz; ++zlev ) {
497 level_cache &cache = get_cache( zlev );
498
499 // Check if any vehicles exist in the active range for this z-level
501 std::any_of( std::begin( cache.veh_exists_at ),
502 std::end( cache.veh_exists_at ), []( const auto & row ) {
503 return std::any_of( std::begin( row ), std::end( row ), []( bool veh_exists ) {
504 return veh_exists;
505 } );
506 } );
507 }
508
509 return true;
510}
vehicle * act_on_map()

References abs_sub, vehicle::act_on_map(), get_cache(), get_vehicles(), vehicle::of_turn, OVERMAP_DEPTH, OVERMAP_HEIGHT, wrapped_vehicle::v, level_cache::veh_exists_at, level_cache::veh_in_active_range, tripoint::z, and zlevels.

Referenced by vehmove().

◆ vertical_shift()

void map::vertical_shift ( int  newz)

Moves the map vertically to (not by!) newz.

Does not actually shift anything, only forces cache updates. In the future, it will either actually shift the map or it will get removed after 3D migration is complete.

Definition at line 6909 of file map.cpp.

6910{
6911 if( !zlevels ) {
6912 debugmsg( "Called map::vertical_shift in a non-z-level world" );
6913 return;
6914 }
6915
6916 if( newz < -OVERMAP_DEPTH || newz > OVERMAP_HEIGHT ) {
6917 debugmsg( "Tried to get z-level %d outside allowed range of %d-%d",
6918 newz, -OVERMAP_DEPTH, OVERMAP_HEIGHT );
6919 return;
6920 }
6921
6922 tripoint trp = get_abs_sub();
6923 set_abs_sub( tripoint( trp.xy(), newz ) );
6924
6925 // TODO: Remove the function when it's safe
6926 return;
6927}

References debugmsg, get_abs_sub(), OVERMAP_DEPTH, OVERMAP_HEIGHT, set_abs_sub(), tripoint::xy(), and zlevels.

Referenced by game::vertical_shift().

◆ water_from()

item map::water_from ( const tripoint p)

Definition at line 4375 of file map.cpp.

4376{
4377 if( has_flag( "SALT_WATER", p ) ) {
4379 }
4380
4381 const ter_id terrain_id = ter( p );
4382 if( terrain_id == t_sewage ) {
4384 ret.poison = rng( 1, 7 );
4385 return ret;
4386 }
4387
4389 // iexamine::water_source requires a valid liquid from this function.
4390 if( terrain_id.obj().examine == &iexamine::water_source ) {
4391 int poison_chance = 0;
4392 if( terrain_id.obj().has_flag( TFLAG_DEEP_WATER ) ) {
4393 if( terrain_id.obj().has_flag( TFLAG_CURRENT ) ) {
4394 poison_chance = 20;
4395 } else {
4396 poison_chance = 4;
4397 }
4398 } else {
4399 if( terrain_id.obj().has_flag( TFLAG_CURRENT ) ) {
4400 poison_chance = 10;
4401 } else {
4402 poison_chance = 3;
4403 }
4404 }
4405 if( one_in( poison_chance ) ) {
4406 ret.poison = rng( 1, 4 );
4407 }
4408 return ret;
4409 }
4410 if( furn( p ).obj().examine == &iexamine::water_source ) {
4411 return ret;
4412 }
4413 return item();
4414}
static const int INFINITE_CHARGES
Definition: item.h:2155
void examine(Character &p, const tripoint &pos)
Calls the examine function of furniture or terrain at given tile, for given character.
Definition: map.cpp:1620
@ TFLAG_CURRENT
Definition: mapdata.h:302
void water_source(player &p, const tripoint &examp)
Definition: iexamine.cpp:3846

References examine(), map_data_common_t::examine, furn(), map_data_common_t::has_flag(), has_flag(), item::INFINITE_CHARGES, int_id< T >::obj(), one_in(), cata::hash64_detail::ret, rng(), calendar::start_of_cataclysm, t_sewage, ter(), TFLAG_CURRENT, TFLAG_DEEP_WATER, and iexamine::water_source().

Referenced by inventory::form_from_map(), use_amount_square(), use_charges(), and iexamine::water_source().

Friends And Related Function Documentation

◆ editmap

friend class editmap
friend

Definition at line 390 of file map.h.

◆ visitable< map_cursor >

friend class visitable< map_cursor >
friend

Definition at line 390 of file map.h.

Member Data Documentation

◆ abs_sub

tripoint map::abs_sub
protected

Absolute coordinates of first submap (get_submap_at(0,0)) This is in submap coordinates (see overmapbuffer for explanation).

It is set upon:

  • loading submap at grid[0],
  • generating submaps (generate)
  • shifting the map with shift

Definition at line 1835 of file map.h.

Referenced by add_item(), add_item_or_charges(), add_vehicle(), adjust_radiation(), apply_faction_ownership(), bash_rating(), bash_resistance(), bash_strength(), build_floor_caches(), can_put_items(), can_put_items_ter_furn(), check_submap_active_item_consistency(), clear_vehicle_cache(), create_anomaly(), decay_fields_and_scent(), detach_vehicle(), draw_fill_background(), draw_lab(), draw_mine(), draw_temple(), draw_triffid(), features(), furn(), furn_set(), furnname(), generate(), get_abs_sub(), get_active_items_in_radius(), get_nonant(), get_submap_at(), get_vehicles(), getabs(), getlocal(), has_flag(), has_flag_furn(), has_flag_ter(), has_flag_ter_or_furn(), has_furn(), i_at(), i_clear(), i_rem(), is_bashable(), is_bashable_furn(), is_bashable_ter(), is_bashable_ter_furn(), is_divable(), is_outside(), is_water_shallow_current(), loadn(), make_active(), move_cost(), move_cost_ter_furn(), name(), passable(), place_items(), place_npc(), place_vending(), points_on_zlevel(), process_fields(), process_fields_in_submap(), process_items(), reset_vehicle_cache(), rotate(), save(), saven(), scent_blockers(), set_abs_sub(), set_radiation(), set_temperature(), spawn_an_item(), spawn_item(), spawn_items(), spawn_monsters(), spawn_monsters_submap(), spawn_monsters_submap_group(), ter(), ter_set(), tername(), update_submap_active_item_status(), update_visibility_cache(), vehmove(), and vehproceed().

◆ caches

std::array< std::unique_ptr<level_cache>, OVERMAP_LAYERS > map::caches
private

Holds caches for visibility, light, transparency and vehicles.

Definition at line 2007 of file map.h.

Referenced by access_cache(), get_cache(), get_cache_ref(), and map().

◆ dirty_vehicle_list

◆ field_furn_locs

std::vector<tripoint> map::field_furn_locs
private

Vector of tripoints containing active field-emitting furniture.

Definition at line 2003 of file map.h.

Referenced by actualize(), furn_set(), get_furn_field_locations(), load(), and shift_traps().

◆ grid

std::vector<submap *> map::grid
private

The list of currently loaded submaps.

The size of this should not be changed. After calling load or generate, it should only contain non-null pointers. Use getsubmap or setsubmap to access it.

Definition at line 1992 of file map.h.

Referenced by actualize(), add_roofs(), clear_spawns(), clear_traps(), editmap::cleartmpmap(), displace_vehicle(), getsubmap(), loadn(), map(), saven(), and setsubmap().

◆ last_full_vehicle_list

VehicleList map::last_full_vehicle_list
private

Vehicle list doesn't change often, but is pretty expensive.

Definition at line 2023 of file map.h.

Referenced by get_vehicles().

◆ last_full_vehicle_list_dirty

bool map::last_full_vehicle_list_dirty = true
private

◆ max_populated_zlev

cata::optional<std::pair<tripoint, int> > map::max_populated_zlev = cata::nullopt
private

Definition at line 2037 of file map.h.

Referenced by calc_max_populated_zlev(), and invalidate_max_populated_zlev().

◆ my_MAPSIZE

◆ pathfinding_caches

std::array< std::unique_ptr<pathfinding_cache>, OVERMAP_LAYERS > map::pathfinding_caches
mutableprivate

Definition at line 2009 of file map.h.

Referenced by get_pathfinding_cache(), get_pathfinding_cache_ref(), and map().

◆ skew_vision_cache

lru_cache<point, char> map::skew_vision_cache
mutableprivate

Cache of coordinate pairs recently checked for visibility.

Definition at line 2018 of file map.h.

Referenced by build_map_cache(), and sees().

◆ submaps_with_active_items

std::set<tripoint> map::submaps_with_active_items
private

◆ support_cache_dirty

std::set<tripoint> map::support_cache_dirty
private

Definition at line 1553 of file map.h.

Referenced by process_falling(), shift(), support_dirty(), and ter_set().

◆ traplocs

std::vector< std::vector<tripoint> > map::traplocs
private

This vector contains an entry for each trap type, it has therefor the same size as the traplist vector.

Each entry contains a list of all point on the map that contain a trap of that type. The first entry however is always empty as it denotes the tr_null trap.

Definition at line 1999 of file map.h.

Referenced by actualize(), clear_traps(), load(), map(), remove_trap(), shift_traps(), ter_set(), trap_locations(), and trap_set().

◆ visibility_variables_cache

visibility_variables map::visibility_variables_cache
private

Definition at line 2033 of file map.h.

Referenced by get_visibility_variables_cache(), and update_visibility_cache().

◆ zlevels


The documentation for this class was generated from the following files: